Compare commits
No commits in common. "master" and "case-sensitivity" have entirely different histories.
master
...
case-sensi
49 changed files with 282 additions and 723 deletions
50
.github/workflows/build.yml
vendored
50
.github/workflows/build.yml
vendored
|
|
@ -1,50 +0,0 @@
|
||||||
name: Build mcume
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
release:
|
|
||||||
types: [published]
|
|
||||||
check_suite:
|
|
||||||
types: [rerequested]
|
|
||||||
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
bins:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Install ARM GCC
|
|
||||||
uses: carlosperate/arm-none-eabi-gcc-action@v1
|
|
||||||
with:
|
|
||||||
release: '13.2.Rel1'
|
|
||||||
|
|
||||||
- name: get submodules
|
|
||||||
run: git submodule update --init
|
|
||||||
|
|
||||||
- name: set up tinyusb
|
|
||||||
run: (cd MCUME_pico2/pico-sdk/lib/tinyusb && git submodule update --init . && python tools/get_deps.py rp2040)
|
|
||||||
|
|
||||||
# https://github.com/sekigon-gonnoc/Pico-PIO-USB/pull/164
|
|
||||||
- name: fix pico-pio-usb ref
|
|
||||||
run: (cd MCUME_pico2/pico-sdk/lib/tinyusb/hw/mcu/raspberry_pi/Pico-PIO-USB && git pull https://github.com/tannewt/Pico-PIO-USB/ better_timeouts)
|
|
||||||
|
|
||||||
- name: build targets
|
|
||||||
run: for target in pico64 pico20 pico800 picospeccy picomsx pico8086 picocolem picogb picopce picosms picogen; do cmake -S MCUME_pico2 -B build -DPICO_SDK_PATH=MCUME_pico2/pico-sdk -DTARGET=$target && make -C build -j$(nproc); done
|
|
||||||
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: uf2 files
|
|
||||||
path: build/*.uf2
|
|
||||||
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: elf files
|
|
||||||
path: build/*.elf
|
|
||||||
|
|
||||||
8
.gitignore
vendored
8
.gitignore
vendored
|
|
@ -1,8 +0,0 @@
|
||||||
# These are files and directories that the user is instructed to create during
|
|
||||||
# the normal build process. Don't offer to commit them to git.
|
|
||||||
*/build
|
|
||||||
|
|
||||||
# Ignores like this that are specific to operating environments are better
|
|
||||||
# expressed in your user-global ignores, because every environment creates
|
|
||||||
# different junk. However, out of expediency, these are ignored anyway:
|
|
||||||
.DS_Store
|
|
||||||
6
.gitmodules
vendored
6
.gitmodules
vendored
|
|
@ -1,6 +0,0 @@
|
||||||
[submodule "MCUME_pico2/pico-sdk"]
|
|
||||||
path = MCUME_pico2/pico-sdk
|
|
||||||
url = https://github.com/raspberrypi/pico-sdk
|
|
||||||
[submodule "MCUME_pico2/pico-extras"]
|
|
||||||
path = MCUME_pico2/pico-extras
|
|
||||||
url = https://github.com/adafruit/pico-extras.git
|
|
||||||
|
|
@ -1,18 +1,14 @@
|
||||||
cmake_minimum_required(VERSION 3.12)
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
|
||||||
set(PICO_PLATFORM rp2350)
|
|
||||||
set(PICO_BOARD pico2)
|
|
||||||
|
|
||||||
# Pull in PICO SDK (must be before project)
|
# Pull in PICO SDK (must be before project)
|
||||||
include(pico_sdk_import.cmake)
|
include(pico_sdk_import.cmake)
|
||||||
|
|
||||||
# We also need PICO EXTRAS
|
# We also need PICO EXTRAS
|
||||||
#include(pico_extras_import.cmake)
|
#include(pico_extras_import.cmake)
|
||||||
|
|
||||||
if (NOT TARGET)
|
|
||||||
#set(TARGET testkeymax)
|
#set(TARGET testkeymax)
|
||||||
#set(TARGET pico20)
|
#set(TARGET pico20)
|
||||||
set(TARGET pico64)
|
#set(TARGET pico64)
|
||||||
#set(TARGET pico81)
|
#set(TARGET pico81)
|
||||||
#set(TARGET pico800)
|
#set(TARGET pico800)
|
||||||
#set(TARGET picospeccy)
|
#set(TARGET picospeccy)
|
||||||
|
|
@ -25,10 +21,9 @@ set(TARGET pico64)
|
||||||
#set(TARGET picopce)
|
#set(TARGET picopce)
|
||||||
#set(TARGET picosms)
|
#set(TARGET picosms)
|
||||||
#set(TARGET picogen)
|
#set(TARGET picogen)
|
||||||
#set(TARGET picocastaway)
|
set(TARGET picocastaway)
|
||||||
#set(TARGET pico5200)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
#set(TARGET pico5200)
|
||||||
|
|
||||||
project(${TARGET} C CXX)
|
project(${TARGET} C CXX)
|
||||||
|
|
||||||
|
|
@ -266,7 +261,6 @@ set(PICO8086_SOURCES
|
||||||
pico8086/i8259.cpp
|
pico8086/i8259.cpp
|
||||||
pico8086/pico8086.cpp
|
pico8086/pico8086.cpp
|
||||||
)
|
)
|
||||||
add_compile_definitions(INCLUDE_ROM_BASIC)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if( ${TARGET} MATCHES "picopce" )
|
if( ${TARGET} MATCHES "picopce" )
|
||||||
|
|
@ -433,13 +427,6 @@ add_executable(${TARGET}
|
||||||
|
|
||||||
pico_generate_pio_header(${TARGET} ${CMAKE_CURRENT_LIST_DIR}/psram/psram_spi.pio)
|
pico_generate_pio_header(${TARGET} ${CMAKE_CURRENT_LIST_DIR}/psram/psram_spi.pio)
|
||||||
|
|
||||||
add_subdirectory(pico-extras/src/rp2_common/pico_audio_i2s)
|
|
||||||
add_subdirectory(pico-extras/src/common/pico_audio)
|
|
||||||
add_subdirectory(pico-extras/src/common/pico_util_buffer)
|
|
||||||
add_compile_definitions(PICO_AUDIO_I2S_PIO=1 PICO_AUDIO_I2S_DMA_IRQ=1 PICO_AUDIO_I2S_DATA_PIN=24 PICO_AUDIO_I2S_CLOCK_PIN_BASE=25 PICO_AUDIO_I2S_MONO_INPUT=1 PICO_AUDIO_I2S_SWAP_CLOCK=1)
|
|
||||||
add_compile_definitions(PICO_DEFAULT_UART=0 PICO_DEFAULT_UART_TX_PIN=44 PICO_DEFAULT_UART_RX_PIN=45)
|
|
||||||
set(EXTRA_AUDIO_LIB pico_util_buffer pico_audio pico_audio_i2s hardware_i2c)
|
|
||||||
|
|
||||||
target_link_libraries(${TARGET} pico_multicore
|
target_link_libraries(${TARGET} pico_multicore
|
||||||
pico_stdlib
|
pico_stdlib
|
||||||
hardware_dma
|
hardware_dma
|
||||||
|
|
@ -450,7 +437,6 @@ target_link_libraries(${TARGET} pico_multicore
|
||||||
tinyusb_host
|
tinyusb_host
|
||||||
tinyusb_board
|
tinyusb_board
|
||||||
tinyusb_pico_pio_usb
|
tinyusb_pico_pio_usb
|
||||||
${EXTRA_AUDIO_LIB}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(${TARGET} PRIVATE
|
target_compile_definitions(${TARGET} PRIVATE
|
||||||
|
|
@ -459,6 +445,7 @@ target_compile_definitions(${TARGET} PRIVATE
|
||||||
|
|
||||||
target_compile_definitions(${TARGET} PRIVATE PICO_CLOCK_AJDUST_PERI_CLOCK_WITH_SYS_CLOCK=1)
|
target_compile_definitions(${TARGET} PRIVATE PICO_CLOCK_AJDUST_PERI_CLOCK_WITH_SYS_CLOCK=1)
|
||||||
|
|
||||||
|
|
||||||
#target_compile_definitions(${TARGET} PRIVATE CFG_TUSB_DEBUG=2)
|
#target_compile_definitions(${TARGET} PRIVATE CFG_TUSB_DEBUG=2)
|
||||||
#target_compile_options(${TARGET} PUBLIC -O3)
|
#target_compile_options(${TARGET} PUBLIC -O3)
|
||||||
#target_compile_options(${TARGET} PUBLIC -Wall -Wextra -Wno-unused-function -Wno-unused-parameter)
|
#target_compile_options(${TARGET} PUBLIC -Wall -Wextra -Wno-unused-function -Wno-unused-parameter)
|
||||||
|
|
|
||||||
BIN
MCUME_pico2/bin/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/bin/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
MCUME_pico2/build/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/build/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
MCUME_pico2/config/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/config/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -13,24 +13,24 @@
|
||||||
// TFT
|
// TFT
|
||||||
#define TFT_SPIREG spi1
|
#define TFT_SPIREG spi1
|
||||||
#define TFT_SPIDREQ DREQ_SPI1_TX
|
#define TFT_SPIDREQ DREQ_SPI1_TX
|
||||||
#define TFT_SCLK 30
|
#define TFT_SCLK 14
|
||||||
#define TFT_MOSI 31
|
#define TFT_MOSI 15
|
||||||
#define TFT_MISO 28
|
#define TFT_MISO 12
|
||||||
#define TFT_DC 3
|
#define TFT_DC 28
|
||||||
#define TFT_CS 46 // 255 for LORES ST7789 (NO CS)
|
#define TFT_CS 13 // 255 for LORES ST7789 (NO CS)
|
||||||
#define TFT_RST 22 // 255 for ILI/ST if connected to 3.3V
|
#define TFT_RST 255 // 255 for ILI/ST if connected to 3.3V
|
||||||
#define TFT_BACKLIGHT 255 // hardwired to 3.3v
|
#define TFT_BACKLIGHT 255 // hardwired to 3.3v
|
||||||
|
|
||||||
// 2 buttons
|
// 2 buttons
|
||||||
#define PIN_KEY_USER1 0
|
#define PIN_KEY_USER1 28
|
||||||
#define PIN_KEY_USER2 4
|
#define PIN_KEY_USER2 27
|
||||||
|
|
||||||
// SD
|
// SD
|
||||||
#define SD_SCLK 34
|
#define SD_SCLK 6
|
||||||
#define SD_MOSI 35
|
#define SD_MOSI 7
|
||||||
#define SD_MISO 36
|
#define SD_MISO 4
|
||||||
#define SD_CS 39
|
#define SD_CS 5
|
||||||
#define SD_DETECT 33
|
#define SD_DETECT 255
|
||||||
// Second SPI bus and DMA not conflicting with USB
|
// Second SPI bus and DMA not conflicting with USB
|
||||||
#define SD_SPIREG spi0
|
#define SD_SPIREG spi0
|
||||||
|
|
||||||
|
|
@ -48,25 +48,4 @@
|
||||||
#define PSRAM_CS 9
|
#define PSRAM_CS 9
|
||||||
|
|
||||||
#define PSRAM_SPIREG spi1
|
#define PSRAM_SPIREG spi1
|
||||||
|
|
||||||
#if 0 // metro rp2350
|
|
||||||
#define PIN_CKN (15u)
|
|
||||||
#define PIN_CKP (14u)
|
|
||||||
#define PIN_D0N (19u)
|
|
||||||
#define PIN_D0P (18u)
|
|
||||||
#define PIN_D1N (17u)
|
|
||||||
#define PIN_D1P (16u)
|
|
||||||
#define PIN_D2N (13u)
|
|
||||||
#define PIN_D2P (12u)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PIN_CKP (13u)
|
|
||||||
#define PIN_D0P (15u)
|
|
||||||
#define PIN_D1P (17u)
|
|
||||||
#define PIN_D2P (19u)
|
|
||||||
|
|
||||||
#define PIN_USB_HOST_DP (1u)
|
|
||||||
#define PIN_USB_HOST_DM (2u)
|
|
||||||
#define PIN_USB_HOST_VBUS (11u)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,8 @@
|
||||||
#define HAS_SND 1
|
#define HAS_SND 1
|
||||||
#define USE_VGA 1
|
#define USE_VGA 1
|
||||||
#define HAS_USBHOST 1
|
#define HAS_USBHOST 1
|
||||||
#define HAS_USBPIO 1
|
//#define HAS_USBPIO 1
|
||||||
|
|
||||||
#define PSRAM_CHIP_SELECT (47u)
|
|
||||||
//#define ILI9341 1
|
//#define ILI9341 1
|
||||||
//#define ST7789 1
|
//#define ST7789 1
|
||||||
//#define SWAP_JOYSTICK 1
|
//#define SWAP_JOYSTICK 1
|
||||||
|
|
|
||||||
BIN
MCUME_pico2/display/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/display/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -5,9 +5,6 @@
|
||||||
#include "pico.h"
|
#include "pico.h"
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "hardware/adc.h"
|
#include "hardware/adc.h"
|
||||||
#include "hardware/structs/qmi.h"
|
|
||||||
#include "hardware/structs/xip.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
@ -20,7 +17,6 @@ extern "C" {
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#include "kbd.h"
|
#include "kbd.h"
|
||||||
#include "pio_usb_configuration.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool emu_writeConfig(void);
|
static bool emu_writeConfig(void);
|
||||||
|
|
@ -1436,175 +1432,20 @@ static bool emu_eraseConfig(void)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _psram_size;
|
|
||||||
static void __no_inline_not_in_flash_func(setup_psram)(void) {
|
|
||||||
_psram_size = 0;
|
|
||||||
#ifdef PSRAM_CHIP_SELECT
|
|
||||||
gpio_set_function(PSRAM_CHIP_SELECT, GPIO_FUNC_XIP_CS1);
|
|
||||||
uint32_t save = save_and_disable_interrupts();
|
|
||||||
// Try and read the PSRAM ID via direct_csr.
|
|
||||||
qmi_hw->direct_csr = 30 << QMI_DIRECT_CSR_CLKDIV_LSB |
|
|
||||||
QMI_DIRECT_CSR_EN_BITS;
|
|
||||||
// Need to poll for the cooldown on the last XIP transfer to expire
|
|
||||||
// (via direct-mode BUSY flag) before it is safe to perform the first
|
|
||||||
// direct-mode operation
|
|
||||||
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exit out of QMI in case we've inited already
|
|
||||||
qmi_hw->direct_csr |= QMI_DIRECT_CSR_ASSERT_CS1N_BITS;
|
|
||||||
// Transmit as quad.
|
|
||||||
qmi_hw->direct_tx = QMI_DIRECT_TX_OE_BITS |
|
|
||||||
QMI_DIRECT_TX_IWIDTH_VALUE_Q << QMI_DIRECT_TX_IWIDTH_LSB |
|
|
||||||
0xf5;
|
|
||||||
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
|
|
||||||
}
|
|
||||||
(void)qmi_hw->direct_rx;
|
|
||||||
qmi_hw->direct_csr &= ~(QMI_DIRECT_CSR_ASSERT_CS1N_BITS);
|
|
||||||
|
|
||||||
// Read the id
|
|
||||||
qmi_hw->direct_csr |= QMI_DIRECT_CSR_ASSERT_CS1N_BITS;
|
|
||||||
uint8_t kgd = 0;
|
|
||||||
uint8_t eid = 0;
|
|
||||||
for (size_t i = 0; i < 7; i++) {
|
|
||||||
if (i == 0) {
|
|
||||||
qmi_hw->direct_tx = 0x9f;
|
|
||||||
} else {
|
|
||||||
qmi_hw->direct_tx = 0xff;
|
|
||||||
}
|
|
||||||
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_TXEMPTY_BITS) == 0) {
|
|
||||||
}
|
|
||||||
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
|
|
||||||
}
|
|
||||||
if (i == 5) {
|
|
||||||
kgd = qmi_hw->direct_rx;
|
|
||||||
} else if (i == 6) {
|
|
||||||
eid = qmi_hw->direct_rx;
|
|
||||||
} else {
|
|
||||||
(void)qmi_hw->direct_rx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Disable direct csr.
|
|
||||||
qmi_hw->direct_csr &= ~(QMI_DIRECT_CSR_ASSERT_CS1N_BITS | QMI_DIRECT_CSR_EN_BITS);
|
|
||||||
|
|
||||||
if (kgd != 0x5D) {
|
|
||||||
restore_interrupts(save);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable quad mode.
|
|
||||||
qmi_hw->direct_csr = 30 << QMI_DIRECT_CSR_CLKDIV_LSB |
|
|
||||||
QMI_DIRECT_CSR_EN_BITS;
|
|
||||||
// Need to poll for the cooldown on the last XIP transfer to expire
|
|
||||||
// (via direct-mode BUSY flag) before it is safe to perform the first
|
|
||||||
// direct-mode operation
|
|
||||||
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// RESETEN, RESET and quad enable
|
|
||||||
for (uint8_t i = 0; i < 3; i++) {
|
|
||||||
qmi_hw->direct_csr |= QMI_DIRECT_CSR_ASSERT_CS1N_BITS;
|
|
||||||
if (i == 0) {
|
|
||||||
qmi_hw->direct_tx = 0x66;
|
|
||||||
} else if (i == 1) {
|
|
||||||
qmi_hw->direct_tx = 0x99;
|
|
||||||
} else {
|
|
||||||
qmi_hw->direct_tx = 0x35;
|
|
||||||
}
|
|
||||||
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
|
|
||||||
}
|
|
||||||
qmi_hw->direct_csr &= ~(QMI_DIRECT_CSR_ASSERT_CS1N_BITS);
|
|
||||||
for (size_t j = 0; j < 20; j++) {
|
|
||||||
asm ("nop");
|
|
||||||
}
|
|
||||||
(void)qmi_hw->direct_rx;
|
|
||||||
}
|
|
||||||
// Disable direct csr.
|
|
||||||
qmi_hw->direct_csr &= ~(QMI_DIRECT_CSR_ASSERT_CS1N_BITS | QMI_DIRECT_CSR_EN_BITS);
|
|
||||||
|
|
||||||
qmi_hw->m[1].timing =
|
|
||||||
QMI_M0_TIMING_PAGEBREAK_VALUE_1024 << QMI_M0_TIMING_PAGEBREAK_LSB | // Break between pages.
|
|
||||||
3 << QMI_M0_TIMING_SELECT_HOLD_LSB | // Delay releasing CS for 3 extra system cycles.
|
|
||||||
1 << QMI_M0_TIMING_COOLDOWN_LSB |
|
|
||||||
1 << QMI_M0_TIMING_RXDELAY_LSB |
|
|
||||||
16 << QMI_M0_TIMING_MAX_SELECT_LSB | // In units of 64 system clock cycles. PSRAM says 8us max. 8 / 0.00752 / 64 = 16.62
|
|
||||||
7 << QMI_M0_TIMING_MIN_DESELECT_LSB | // In units of system clock cycles. PSRAM says 50ns.50 / 7.52 = 6.64
|
|
||||||
2 << QMI_M0_TIMING_CLKDIV_LSB;
|
|
||||||
qmi_hw->m[1].rfmt = (QMI_M0_RFMT_PREFIX_WIDTH_VALUE_Q << QMI_M0_RFMT_PREFIX_WIDTH_LSB |
|
|
||||||
QMI_M0_RFMT_ADDR_WIDTH_VALUE_Q << QMI_M0_RFMT_ADDR_WIDTH_LSB |
|
|
||||||
QMI_M0_RFMT_SUFFIX_WIDTH_VALUE_Q << QMI_M0_RFMT_SUFFIX_WIDTH_LSB |
|
|
||||||
QMI_M0_RFMT_DUMMY_WIDTH_VALUE_Q << QMI_M0_RFMT_DUMMY_WIDTH_LSB |
|
|
||||||
QMI_M0_RFMT_DUMMY_LEN_VALUE_24 << QMI_M0_RFMT_DUMMY_LEN_LSB |
|
|
||||||
QMI_M0_RFMT_DATA_WIDTH_VALUE_Q << QMI_M0_RFMT_DATA_WIDTH_LSB |
|
|
||||||
QMI_M0_RFMT_PREFIX_LEN_VALUE_8 << QMI_M0_RFMT_PREFIX_LEN_LSB |
|
|
||||||
QMI_M0_RFMT_SUFFIX_LEN_VALUE_NONE << QMI_M0_RFMT_SUFFIX_LEN_LSB);
|
|
||||||
qmi_hw->m[1].rcmd = 0xeb << QMI_M0_RCMD_PREFIX_LSB |
|
|
||||||
0 << QMI_M0_RCMD_SUFFIX_LSB;
|
|
||||||
qmi_hw->m[1].wfmt = (QMI_M0_WFMT_PREFIX_WIDTH_VALUE_Q << QMI_M0_WFMT_PREFIX_WIDTH_LSB |
|
|
||||||
QMI_M0_WFMT_ADDR_WIDTH_VALUE_Q << QMI_M0_WFMT_ADDR_WIDTH_LSB |
|
|
||||||
QMI_M0_WFMT_SUFFIX_WIDTH_VALUE_Q << QMI_M0_WFMT_SUFFIX_WIDTH_LSB |
|
|
||||||
QMI_M0_WFMT_DUMMY_WIDTH_VALUE_Q << QMI_M0_WFMT_DUMMY_WIDTH_LSB |
|
|
||||||
QMI_M0_WFMT_DUMMY_LEN_VALUE_NONE << QMI_M0_WFMT_DUMMY_LEN_LSB |
|
|
||||||
QMI_M0_WFMT_DATA_WIDTH_VALUE_Q << QMI_M0_WFMT_DATA_WIDTH_LSB |
|
|
||||||
QMI_M0_WFMT_PREFIX_LEN_VALUE_8 << QMI_M0_WFMT_PREFIX_LEN_LSB |
|
|
||||||
QMI_M0_WFMT_SUFFIX_LEN_VALUE_NONE << QMI_M0_WFMT_SUFFIX_LEN_LSB);
|
|
||||||
qmi_hw->m[1].wcmd = 0x38 << QMI_M0_WCMD_PREFIX_LSB |
|
|
||||||
0 << QMI_M0_WCMD_SUFFIX_LSB;
|
|
||||||
|
|
||||||
restore_interrupts(save);
|
|
||||||
|
|
||||||
_psram_size = 1024 * 1024; // 1 MiB
|
|
||||||
uint8_t size_id = eid >> 5;
|
|
||||||
if (eid == 0x26 || size_id == 2) {
|
|
||||||
_psram_size *= 8;
|
|
||||||
} else if (size_id == 0) {
|
|
||||||
_psram_size *= 2;
|
|
||||||
} else if (size_id == 1) {
|
|
||||||
_psram_size *= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark that we can write to PSRAM.
|
|
||||||
xip_ctrl_hw->ctrl |= XIP_CTRL_WRITABLE_M1_BITS;
|
|
||||||
|
|
||||||
// Test write to the PSRAM.
|
|
||||||
volatile uint32_t *psram_nocache = (volatile uint32_t *)0x15000000;
|
|
||||||
psram_nocache[0] = 0x12345678;
|
|
||||||
volatile uint32_t readback = psram_nocache[0];
|
|
||||||
if (readback != 0x12345678) {
|
|
||||||
_psram_size = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************
|
/********************************
|
||||||
* Initialization
|
* Initialization
|
||||||
********************************/
|
********************************/
|
||||||
void emu_init(void)
|
void emu_init(void)
|
||||||
{
|
{
|
||||||
setup_psram();
|
|
||||||
|
|
||||||
//board_init();
|
//board_init();
|
||||||
stdio_init_all();
|
stdio_init_all();
|
||||||
|
|
||||||
bool forceVga = false;
|
bool forceVga = false;
|
||||||
|
|
||||||
#ifdef HAS_USBHOST
|
#ifdef HAS_USBHOST
|
||||||
pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG;
|
|
||||||
_Static_assert(PIN_USB_HOST_DP + 1 == PIN_USB_HOST_DM || PIN_USB_HOST_DP - 1 == PIN_USB_HOST_DM, "Permitted USB D+/D- configuration");
|
|
||||||
pio_cfg.pinout = PIN_USB_HOST_DP + 1 == PIN_USB_HOST_DM ? PIO_USB_PINOUT_DPDM : PIO_USB_PINOUT_DMDP;
|
|
||||||
pio_cfg.pin_dp = PIN_USB_HOST_DP;
|
|
||||||
|
|
||||||
#ifdef PIN_USB_HOST_VBUS
|
|
||||||
printf("Enabling USB host VBUS power on GP%d\r\n", PIN_USB_HOST_VBUS);
|
|
||||||
gpio_init(PIN_USB_HOST_VBUS);
|
|
||||||
gpio_set_dir(PIN_USB_HOST_VBUS, GPIO_OUT);
|
|
||||||
gpio_put(PIN_USB_HOST_VBUS, 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
tuh_configure(BOARD_TUH_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg);
|
|
||||||
printf("Init USB...\n");
|
printf("Init USB...\n");
|
||||||
printf("USB D+/D- on GP%d and GP%d\r\n", PIN_USB_HOST_DP, PIN_USB_HOST_DM);
|
printf("USB D+/D- on GP%d and GP%d\r\n", PIO_USB_DP_PIN_DEFAULT, PIO_USB_DP_PIN_DEFAULT+1);
|
||||||
printf("TinyUSB Host HID Controller Example\r\n");
|
printf("TinyUSB Host HID Controller Example\r\n");
|
||||||
tuh_init(BOARD_TUH_RHPORT);
|
tuh_init(BOARD_TUH_RHPORT);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1712,9 +1553,6 @@ int keypressed = emu_ReadKeys();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void kbd_signal_raw_gamepad(uint16_t new_pad_state) {
|
|
||||||
usbnavpad = new_pad_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void emu_start(void)
|
void emu_start(void)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -337,25 +337,23 @@ void hdmi_framebuffer(hdmi_framebuffer_obj_t *self, uint16_t width, uint16_t hei
|
||||||
// 250 Mbps, which is very close to the bit clock for 480p 60Hz (252 MHz).
|
// 250 Mbps, which is very close to the bit clock for 480p 60Hz (252 MHz).
|
||||||
// If we want the exact rate then we'll have to reconfigure PLLs.
|
// If we want the exact rate then we'll have to reconfigure PLLs.
|
||||||
|
|
||||||
// HSTX outputs 0 through 7 appear on GPIO 12 through 19.
|
|
||||||
constexpr int HSTX_FIRST_PIN = 12;
|
|
||||||
struct { uint8_t clk_p, rgb_p[3]; } pinout = { PIN_CKP, PIN_D0P, PIN_D1P, PIN_D2P };
|
|
||||||
|
|
||||||
// Assign clock pair to two neighbouring pins:
|
// Assign clock pair to two neighbouring pins:
|
||||||
hstx_ctrl_hw->bit[(pinout.clk_p ) - HSTX_FIRST_PIN] = HSTX_CTRL_BIT0_CLK_BITS;
|
hstx_ctrl_hw->bit[2] = HSTX_CTRL_BIT0_CLK_BITS;
|
||||||
hstx_ctrl_hw->bit[(pinout.clk_p ^ 1) - HSTX_FIRST_PIN] = HSTX_CTRL_BIT0_CLK_BITS | HSTX_CTRL_BIT0_INV_BITS;
|
hstx_ctrl_hw->bit[3] = HSTX_CTRL_BIT0_CLK_BITS | HSTX_CTRL_BIT0_INV_BITS;
|
||||||
for (uint lane = 0; lane < 3; ++lane) {
|
for (uint lane = 0; lane < 3; ++lane) {
|
||||||
// For each TMDS lane, assign it to the correct GPIO pair based on the
|
// For each TMDS lane, assign it to the correct GPIO pair based on the
|
||||||
// desired pinout:
|
// desired pinout:
|
||||||
int bit = pinout.rgb_p[lane];
|
static const int lane_to_output_bit[3] = {0, 6, 4};
|
||||||
// Output even bits during first half of each HSTX cycle, and odd bits
|
int bit = lane_to_output_bit[lane];
|
||||||
// during second half. The shifter advances by two bits each cycle.
|
// Output even bits during first half of each HSTX cycle, and odd bits
|
||||||
uint32_t lane_data_sel_bits =
|
// during second half. The shifter advances by two bits each cycle.
|
||||||
(lane * 10 ) << HSTX_CTRL_BIT0_SEL_P_LSB |
|
uint32_t lane_data_sel_bits =
|
||||||
(lane * 10 + 1) << HSTX_CTRL_BIT0_SEL_N_LSB;
|
(lane * 10 ) << HSTX_CTRL_BIT0_SEL_P_LSB |
|
||||||
// The two halves of each pair get identical data, but one pin is inverted.
|
(lane * 10 + 1) << HSTX_CTRL_BIT0_SEL_N_LSB;
|
||||||
hstx_ctrl_hw->bit[(bit ) - HSTX_FIRST_PIN] = lane_data_sel_bits;
|
// The two halves of each pair get identical data, but one pin is inverted.
|
||||||
hstx_ctrl_hw->bit[(bit ^ 1) - HSTX_FIRST_PIN] = lane_data_sel_bits | HSTX_CTRL_BIT0_INV_BITS;
|
hstx_ctrl_hw->bit[bit ] = lane_data_sel_bits;
|
||||||
|
hstx_ctrl_hw->bit[bit + 1] = lane_data_sel_bits | HSTX_CTRL_BIT0_INV_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 12; i <= 19; ++i) {
|
for (int i = 12; i <= 19; ++i) {
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,6 @@ static volatile bool cancelled = false;
|
||||||
static volatile uint8_t curTransfer = 0;
|
static volatile uint8_t curTransfer = 0;
|
||||||
static uint8_t nbTransfer = 0;
|
static uint8_t nbTransfer = 0;
|
||||||
|
|
||||||
#undef B16
|
|
||||||
/* VGA structures / constants */
|
/* VGA structures / constants */
|
||||||
#define R16(rgb) ((rgb>>8)&0xf8)
|
#define R16(rgb) ((rgb>>8)&0xf8)
|
||||||
#define G16(rgb) ((rgb>>3)&0xfc)
|
#define G16(rgb) ((rgb>>3)&0xfc)
|
||||||
|
|
@ -1278,308 +1277,206 @@ void PICO_DSP::drawTextNoDma(int16_t x, int16_t y, const char * text, dsp_pixel
|
||||||
#include "pico/float.h"
|
#include "pico/float.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "pico/audio_i2s.h"
|
|
||||||
#include "hardware/i2c.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef AUDIO_1DMA
|
||||||
|
#define SAMPLE_REPEAT_SHIFT 0 // not possible to repeat samples with single DMA!!
|
||||||
|
#endif
|
||||||
|
#ifdef AUDIO_3DMA
|
||||||
|
#define SAMPLE_REPEAT_SHIFT 2 // shift 2 is REPETITION_RATE=4
|
||||||
|
#endif
|
||||||
|
#ifndef SAMPLE_REPEAT_SHIFT
|
||||||
|
#define SAMPLE_REPEAT_SHIFT 0 // not possible to repeat samples CBACK!!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define REPETITION_RATE (1<<SAMPLE_REPEAT_SHIFT)
|
||||||
|
|
||||||
static void (*fillsamples)(audio_sample * stream, int len) = nullptr;
|
static void (*fillsamples)(audio_sample * stream, int len) = nullptr;
|
||||||
|
static audio_sample * snd_buffer; // samples buffer (1 malloc for 2 buffers)
|
||||||
|
static uint16_t snd_nb_samples; // total nb samples (mono) later divided by 2
|
||||||
|
static uint16_t snd_sample_ptr = 0; // sample index
|
||||||
|
static audio_sample * audio_buffers[2]; // pointers to 2 samples buffers
|
||||||
|
static volatile int cur_audio_buffer;
|
||||||
|
static volatile int last_audio_buffer;
|
||||||
|
#ifdef AUDIO_3DMA
|
||||||
|
static uint32_t single_sample = 0;
|
||||||
|
static uint32_t *single_sample_ptr = &single_sample;
|
||||||
|
static int pwm_dma_chan, trigger_dma_chan, sample_dma_chan;
|
||||||
|
#endif
|
||||||
|
#ifdef AUDIO_1DMA
|
||||||
|
static int pwm_dma_chan;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Processing
|
||||||
|
********************************/
|
||||||
|
#ifdef AUDIO_1DMA
|
||||||
|
static void __isr __time_critical_func(AUDIO_isr)()
|
||||||
|
{
|
||||||
|
cur_audio_buffer = 1 - cur_audio_buffer;
|
||||||
|
dma_hw->ch[pwm_dma_chan].al3_read_addr_trig = (intptr_t)audio_buffers[cur_audio_buffer];
|
||||||
|
dma_hw->ints1 = (1u << pwm_dma_chan);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef AUDIO_3DMA
|
||||||
|
static void __isr __time_critical_func(AUDIO_isr)()
|
||||||
|
{
|
||||||
|
cur_audio_buffer = 1 - cur_audio_buffer;
|
||||||
|
dma_hw->ch[sample_dma_chan].al1_read_addr = (intptr_t)audio_buffers[cur_audio_buffer];
|
||||||
|
dma_hw->ch[trigger_dma_chan].al3_read_addr_trig = (intptr_t)&single_sample_ptr;
|
||||||
|
dma_hw->ints1 = (1u << trigger_dma_chan);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// fill half buffer depending on current position
|
||||||
|
static void pwm_audio_handle_buffer(void)
|
||||||
|
{
|
||||||
|
if (last_audio_buffer == cur_audio_buffer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
audio_sample *buf = audio_buffers[last_audio_buffer];
|
||||||
|
last_audio_buffer = cur_audio_buffer;
|
||||||
|
fillsamples(buf, snd_nb_samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pwm_audio_reset(void)
|
||||||
|
{
|
||||||
|
memset((void*)snd_buffer,0, snd_nb_samples*sizeof(uint8_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/********************************
|
/********************************
|
||||||
* Initialization
|
* Initialization
|
||||||
********************************/
|
********************************/
|
||||||
struct audio_buffer_pool *producer_pool;
|
static void pwm_audio_init(int buffersize, void (*callback)(audio_sample * stream, int len))
|
||||||
|
|
||||||
#if AUDIO_8BIT
|
|
||||||
_Static_assert(!AUDIO_8BIT, "only configured for 16 bit audio");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static audio_format_t audio_format = {
|
|
||||||
.sample_freq = SOUNDRATE,
|
|
||||||
.format = AUDIO_BUFFER_FORMAT_PCM_S16,
|
|
||||||
.channel_count = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct audio_i2s_config config =
|
|
||||||
{
|
|
||||||
.data_pin = PICO_AUDIO_I2S_DATA_PIN,
|
|
||||||
.clock_pin_base = PICO_AUDIO_I2S_CLOCK_PIN_BASE,
|
|
||||||
.dma_channel = AUD_DMA_CHANNEL,
|
|
||||||
.pio_sm = 0,
|
|
||||||
.clock_pins_swapped = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct audio_buffer_format producer_format = {
|
|
||||||
.format = &audio_format,
|
|
||||||
.sample_stride = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
#define I2C_ADDR 0x18
|
|
||||||
|
|
||||||
#define DEBUG_I2C (0)
|
|
||||||
static void writeRegister(uint8_t reg, uint8_t value) {
|
|
||||||
uint8_t buf[2];
|
|
||||||
buf[0] = reg;
|
|
||||||
buf[1] = value;
|
|
||||||
int res = i2c_write_timeout_us(i2c0, I2C_ADDR, buf, sizeof(buf), /* nostop */ false, 1000);
|
|
||||||
if (res != 2) {
|
|
||||||
panic("i2c_write_timeout failed: res=%d\n", res);
|
|
||||||
}
|
|
||||||
if(DEBUG_I2C)
|
|
||||||
printf("Write Reg: %d = 0x%x\n", reg, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t readRegister(uint8_t reg) {
|
|
||||||
uint8_t buf[1];
|
|
||||||
buf[0] = reg;
|
|
||||||
int res = i2c_write_timeout_us(i2c0, I2C_ADDR, buf, sizeof(buf), /* nostop */ true, 1000);
|
|
||||||
if (res != 1) {
|
|
||||||
if(DEBUG_I2C)
|
|
||||||
printf("res=%d\n", res);
|
|
||||||
panic("i2c_write_timeout failed: res=%d\n", res);
|
|
||||||
}
|
|
||||||
res = i2c_read_timeout_us(i2c0, I2C_ADDR, buf, sizeof(buf), /* nostop */ false, 1000);
|
|
||||||
if (res != 1) {
|
|
||||||
if(DEBUG_I2C)
|
|
||||||
printf("res=%d\n", res);
|
|
||||||
panic("i2c_read_timeout failed: res=%d\n", res);
|
|
||||||
}
|
|
||||||
uint8_t value = buf[0];
|
|
||||||
if(DEBUG_I2C)
|
|
||||||
printf("Read Reg: %d = 0x%x\n", reg, value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void modifyRegister(uint8_t reg, uint8_t mask, uint8_t value) {
|
|
||||||
uint8_t current = readRegister(reg);
|
|
||||||
if(DEBUG_I2C)
|
|
||||||
printf("Modify Reg: %d = [Before: 0x%x] with mask 0x%x and value 0x%x\n", reg, current, mask, value);
|
|
||||||
uint8_t new_value = (current & ~mask) | (value & mask);
|
|
||||||
writeRegister(reg, new_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setPage(uint8_t page) {
|
|
||||||
printf("Set page %d\n", page);
|
|
||||||
writeRegister(0x00, page);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void Wire_begin() {
|
|
||||||
i2c_init(i2c0, 100000);
|
|
||||||
gpio_set_function(20, GPIO_FUNC_I2C);
|
|
||||||
gpio_set_function(21, GPIO_FUNC_I2C);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void i2s_audio_init(void)
|
|
||||||
{
|
{
|
||||||
|
fillsamples = callback;
|
||||||
|
snd_nb_samples = buffersize;
|
||||||
|
snd_sample_ptr = 0;
|
||||||
|
snd_buffer = (audio_sample*)malloc(snd_nb_samples*sizeof(audio_sample));
|
||||||
|
if (snd_buffer == NULL) {
|
||||||
|
printf("sound buffer could not be allocated!!!!!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset((void*)snd_buffer,128, snd_nb_samples*sizeof(audio_sample));
|
||||||
|
|
||||||
gpio_init(22);
|
gpio_set_function(AUDIO_PIN, GPIO_FUNC_PWM);
|
||||||
gpio_set_dir(22, true);
|
|
||||||
gpio_put(22, true); // allow i2s to come out of reset
|
|
||||||
|
|
||||||
Wire_begin();
|
int audio_pin_slice = pwm_gpio_to_slice_num(AUDIO_PIN);
|
||||||
sleep_ms(1000);
|
pwm_set_gpio_level(AUDIO_PIN, 0);
|
||||||
|
|
||||||
if(DEBUG_I2C)
|
|
||||||
printf("initialize codec\n");
|
|
||||||
|
|
||||||
// Reset codec
|
// Setup PWM for audio output
|
||||||
writeRegister(0x01, 0x01);
|
pwm_config config = pwm_get_default_config();
|
||||||
sleep_ms(10);
|
pwm_config_set_clkdiv(&config, (((float)SOUNDRATE)/1000) / REPETITION_RATE);
|
||||||
|
pwm_config_set_wrap(&config, 254);
|
||||||
|
pwm_init(audio_pin_slice, &config, true);
|
||||||
|
|
||||||
// Interface Control
|
snd_nb_samples = snd_nb_samples/2;
|
||||||
modifyRegister(0x1B, 0xC0, 0x00);
|
audio_buffers[0] = &snd_buffer[0];
|
||||||
modifyRegister(0x1B, 0x30, 0x00);
|
audio_buffers[1] = &snd_buffer[snd_nb_samples];
|
||||||
|
|
||||||
// Clock MUX and PLL settings
|
#ifdef AUDIO_3DMA
|
||||||
modifyRegister(0x04, 0x03, 0x03);
|
int audio_pin_chan = pwm_gpio_to_channel(AUDIO_PIN);
|
||||||
modifyRegister(0x04, 0x0C, 0x04);
|
// DMA chain of 3 DMA channels
|
||||||
|
sample_dma_chan = AUD_DMA_CHANNEL;
|
||||||
writeRegister(0x06, 0x20); // PLL J
|
pwm_dma_chan = AUD_DMA_CHANNEL+1;
|
||||||
writeRegister(0x08, 0x00); // PLL D LSB
|
trigger_dma_chan = AUD_DMA_CHANNEL+2;
|
||||||
writeRegister(0x07, 0x00); // PLL D MSB
|
|
||||||
|
|
||||||
modifyRegister(0x05, 0x0F, 0x02); // PLL P/R
|
|
||||||
modifyRegister(0x05, 0x70, 0x10);
|
|
||||||
|
|
||||||
// DAC/ADC Config
|
// setup PWM DMA channel
|
||||||
modifyRegister(0x0B, 0x7F, 0x08); // NDAC
|
dma_channel_config pwm_dma_chan_config = dma_channel_get_default_config(pwm_dma_chan);
|
||||||
modifyRegister(0x0B, 0x80, 0x80);
|
channel_config_set_transfer_data_size(&pwm_dma_chan_config, DMA_SIZE_32); // transfer 32 bits at a time
|
||||||
|
channel_config_set_read_increment(&pwm_dma_chan_config, false); // always read from the same address
|
||||||
modifyRegister(0x0C, 0x7F, 0x02); // MDAC
|
channel_config_set_write_increment(&pwm_dma_chan_config, false); // always write to the same address
|
||||||
modifyRegister(0x0C, 0x80, 0x80);
|
channel_config_set_chain_to(&pwm_dma_chan_config, sample_dma_chan); // trigger sample DMA channel when done
|
||||||
|
channel_config_set_dreq(&pwm_dma_chan_config, DREQ_PWM_WRAP0 + audio_pin_slice); // transfer on PWM cycle end
|
||||||
modifyRegister(0x12, 0x7F, 0x08); // NADC
|
dma_channel_configure(pwm_dma_chan,
|
||||||
modifyRegister(0x12, 0x80, 0x80);
|
&pwm_dma_chan_config,
|
||||||
|
&pwm_hw->slice[audio_pin_slice].cc, // write to PWM slice CC register
|
||||||
modifyRegister(0x13, 0x7F, 0x02); // MADC
|
&single_sample, // read from single_sample
|
||||||
modifyRegister(0x13, 0x80, 0x80);
|
REPETITION_RATE, // transfer once per desired sample repetition
|
||||||
|
false // don't start yet
|
||||||
// PLL Power Up
|
);
|
||||||
modifyRegister(0x05, 0x80, 0x80);
|
|
||||||
|
|
||||||
// Headset and GPIO Config
|
|
||||||
setPage(1);
|
|
||||||
modifyRegister(0x2e, 0xFF, 0x0b);
|
|
||||||
setPage(0);
|
|
||||||
modifyRegister(0x43, 0x80, 0x80); // Headset Detect
|
|
||||||
modifyRegister(0x30, 0x80, 0x80); // INT1 Control
|
|
||||||
modifyRegister(0x33, 0x3C, 0x14); // GPIO1
|
|
||||||
|
|
||||||
|
|
||||||
// DAC Setup
|
// setup trigger DMA channel
|
||||||
modifyRegister(0x3F, 0xC0, 0xC0);
|
dma_channel_config trigger_dma_chan_config = dma_channel_get_default_config(trigger_dma_chan);
|
||||||
|
channel_config_set_transfer_data_size(&trigger_dma_chan_config, DMA_SIZE_32); // transfer 32-bits at a time
|
||||||
|
channel_config_set_read_increment(&trigger_dma_chan_config, false); // always read from the same address
|
||||||
|
channel_config_set_write_increment(&trigger_dma_chan_config, false); // always write to the same address
|
||||||
|
channel_config_set_dreq(&trigger_dma_chan_config, DREQ_PWM_WRAP0 + audio_pin_slice); // transfer on PWM cycle end
|
||||||
|
dma_channel_configure(trigger_dma_chan,
|
||||||
|
&trigger_dma_chan_config,
|
||||||
|
&dma_hw->ch[pwm_dma_chan].al3_read_addr_trig, // write to PWM DMA channel read address trigger
|
||||||
|
&single_sample_ptr, // read from location containing the address of single_sample
|
||||||
|
REPETITION_RATE * snd_nb_samples, // trigger once per audio sample per repetition rate
|
||||||
|
false // don't start yet
|
||||||
|
);
|
||||||
|
dma_channel_set_irq1_enabled(trigger_dma_chan, true); // fire interrupt when trigger DMA channel is done
|
||||||
|
irq_set_exclusive_handler(DMA_IRQ_1, AUDIO_isr);
|
||||||
|
irq_set_priority (DMA_IRQ_1, PICO_DEFAULT_IRQ_PRIORITY-8);
|
||||||
|
irq_set_enabled(DMA_IRQ_1, true);
|
||||||
|
|
||||||
// DAC Routing
|
// setup sample DMA channel
|
||||||
setPage(1);
|
dma_channel_config sample_dma_chan_config = dma_channel_get_default_config(sample_dma_chan);
|
||||||
modifyRegister(0x23, 0xC0, 0x40);
|
channel_config_set_transfer_data_size(&sample_dma_chan_config, DMA_SIZE_8); // transfer 8-bits at a time
|
||||||
modifyRegister(0x23, 0x0C, 0x04);
|
channel_config_set_read_increment(&sample_dma_chan_config, true); // increment read address to go through audio buffer
|
||||||
|
channel_config_set_write_increment(&sample_dma_chan_config, false); // always write to the same address
|
||||||
|
dma_channel_configure(sample_dma_chan,
|
||||||
|
&sample_dma_chan_config,
|
||||||
|
(char*)&single_sample + 2*audio_pin_chan, // write to single_sample
|
||||||
|
snd_buffer, // read from audio buffer
|
||||||
|
1, // only do one transfer (once per PWM DMA completion due to chaining)
|
||||||
|
false // don't start yet
|
||||||
|
);
|
||||||
|
|
||||||
// DAC Volume Control
|
// Kick things off with the trigger DMA channel
|
||||||
setPage(0);
|
dma_channel_start(trigger_dma_chan);
|
||||||
modifyRegister(0x40, 0x0C, 0x00);
|
#endif
|
||||||
writeRegister(0x41, 0x28); // Left DAC Vol
|
#ifdef AUDIO_1DMA
|
||||||
writeRegister(0x42, 0x28); // Right DAC Vol
|
// Each sample played from a single DMA channel
|
||||||
|
// Setup DMA channel to drive the PWM
|
||||||
|
pwm_dma_chan = AUD_DMA_CHANNEL;
|
||||||
|
dma_channel_config pwm_dma_chan_config = dma_channel_get_default_config(pwm_dma_chan);
|
||||||
|
// Transfer 16 bits at once, increment read address to go through sample
|
||||||
|
// buffer, always write to the same address (PWM slice CC register).
|
||||||
|
channel_config_set_transfer_data_size(&pwm_dma_chan_config, DMA_SIZE_16);
|
||||||
|
channel_config_set_read_increment(&pwm_dma_chan_config, true);
|
||||||
|
channel_config_set_write_increment(&pwm_dma_chan_config, false);
|
||||||
|
// Transfer on PWM cycle end
|
||||||
|
channel_config_set_dreq(&pwm_dma_chan_config, DREQ_PWM_WRAP0 + audio_pin_slice);
|
||||||
|
|
||||||
// ADC Setup
|
// Setup the channel and set it going
|
||||||
modifyRegister(0x51, 0x80, 0x80);
|
dma_channel_configure(
|
||||||
modifyRegister(0x52, 0x80, 0x00);
|
pwm_dma_chan,
|
||||||
writeRegister(0x53, 0x68); // ADC Volume
|
&pwm_dma_chan_config,
|
||||||
|
&pwm_hw->slice[audio_pin_slice].cc, // Write to PWM counter compare
|
||||||
|
snd_buffer, // Read values from audio buffer
|
||||||
|
snd_nb_samples,
|
||||||
|
false // Start immediately if true.
|
||||||
|
);
|
||||||
|
|
||||||
// Headphone and Speaker Setup
|
// Setup interrupt handler to fire when PWM DMA channel has gone through the
|
||||||
setPage(1);
|
// whole audio buffer
|
||||||
modifyRegister(0x1F, 0xC0, 0xC0); // HP Driver
|
dma_channel_set_irq1_enabled(pwm_dma_chan, true);
|
||||||
modifyRegister(0x28, 0x04, 0x04); // HP Left Gain
|
irq_set_exclusive_handler(DMA_IRQ_1, AUDIO_isr);
|
||||||
modifyRegister(0x29, 0x04, 0x04); // HP Right Gain
|
//irq_set_priority (DMA_IRQ_1, PICO_DEFAULT_IRQ_PRIORITY-8);
|
||||||
writeRegister(0x24, 0x0A); // Left Analog HP
|
irq_set_enabled(DMA_IRQ_1, true);
|
||||||
writeRegister(0x25, 0x0A); // Right Analog HP
|
dma_channel_start(pwm_dma_chan);
|
||||||
|
#endif
|
||||||
modifyRegister(0x28, 0x78, 0x40); // HP Left Gain
|
|
||||||
modifyRegister(0x29, 0x78, 0x40); // HP Right Gain
|
|
||||||
|
|
||||||
// Speaker Amp
|
|
||||||
modifyRegister(0x20, 0x80, 0x80);
|
|
||||||
modifyRegister(0x2A, 0x04, 0x04);
|
|
||||||
modifyRegister(0x2A, 0x18, 0x08);
|
|
||||||
writeRegister(0x26, 0x0A);
|
|
||||||
|
|
||||||
// Return to page 0
|
|
||||||
setPage(0);
|
|
||||||
|
|
||||||
if(DEBUG_I2C)
|
|
||||||
printf("Initialization complete!\n");
|
|
||||||
|
|
||||||
|
|
||||||
// Read all registers for verification
|
|
||||||
if(DEBUG_I2C) {
|
|
||||||
printf("Reading all registers for verification:\n");
|
|
||||||
|
|
||||||
setPage(0);
|
|
||||||
readRegister(0x00); // AIC31XX_PAGECTL
|
|
||||||
readRegister(0x01); // AIC31XX_RESET
|
|
||||||
readRegister(0x03); // AIC31XX_OT_FLAG
|
|
||||||
readRegister(0x04); // AIC31XX_CLKMUX
|
|
||||||
readRegister(0x05); // AIC31XX_PLLPR
|
|
||||||
readRegister(0x06); // AIC31XX_PLLJ
|
|
||||||
readRegister(0x07); // AIC31XX_PLLDMSB
|
|
||||||
readRegister(0x08); // AIC31XX_PLLDLSB
|
|
||||||
readRegister(0x0B); // AIC31XX_NDAC
|
|
||||||
readRegister(0x0C); // AIC31XX_MDAC
|
|
||||||
readRegister(0x0D); // AIC31XX_DOSRMSB
|
|
||||||
readRegister(0x0E); // AIC31XX_DOSRLSB
|
|
||||||
readRegister(0x10); // AIC31XX_MINI_DSP_INPOL
|
|
||||||
readRegister(0x12); // AIC31XX_NADC
|
|
||||||
readRegister(0x13); // AIC31XX_MADC
|
|
||||||
readRegister(0x14); // AIC31XX_AOSR
|
|
||||||
readRegister(0x19); // AIC31XX_CLKOUTMUX
|
|
||||||
readRegister(0x1A); // AIC31XX_CLKOUTMVAL
|
|
||||||
readRegister(0x1B); // AIC31XX_IFACE1
|
|
||||||
readRegister(0x1C); // AIC31XX_DATA_OFFSET
|
|
||||||
readRegister(0x1D); // AIC31XX_IFACE2
|
|
||||||
readRegister(0x1E); // AIC31XX_BCLKN
|
|
||||||
readRegister(0x1F); // AIC31XX_IFACESEC1
|
|
||||||
readRegister(0x20); // AIC31XX_IFACESEC2
|
|
||||||
readRegister(0x21); // AIC31XX_IFACESEC3
|
|
||||||
readRegister(0x22); // AIC31XX_I2C
|
|
||||||
readRegister(0x24); // AIC31XX_ADCFLAG
|
|
||||||
readRegister(0x25); // AIC31XX_DACFLAG1
|
|
||||||
readRegister(0x26); // AIC31XX_DACFLAG2
|
|
||||||
readRegister(0x27); // AIC31XX_OFFLAG
|
|
||||||
readRegister(0x2C); // AIC31XX_INTRDACFLAG
|
|
||||||
readRegister(0x2D); // AIC31XX_INTRADCFLAG
|
|
||||||
readRegister(0x2E); // AIC31XX_INTRDACFLAG2
|
|
||||||
readRegister(0x2F); // AIC31XX_INTRADCFLAG2
|
|
||||||
readRegister(0x30); // AIC31XX_INT1CTRL
|
|
||||||
readRegister(0x31); // AIC31XX_INT2CTRL
|
|
||||||
readRegister(0x33); // AIC31XX_GPIO1
|
|
||||||
readRegister(0x3C); // AIC31XX_DACPRB
|
|
||||||
readRegister(0x3D); // AIC31XX_ADCPRB
|
|
||||||
readRegister(0x3F); // AIC31XX_DACSETUP
|
|
||||||
readRegister(0x40); // AIC31XX_DACMUTE
|
|
||||||
readRegister(0x41); // AIC31XX_LDACVOL
|
|
||||||
readRegister(0x42); // AIC31XX_RDACVOL
|
|
||||||
readRegister(0x43); // AIC31XX_HSDETECT
|
|
||||||
readRegister(0x51); // AIC31XX_ADCSETUP
|
|
||||||
readRegister(0x52); // AIC31XX_ADCFGA
|
|
||||||
readRegister(0x53); // AIC31XX_ADCVOL
|
|
||||||
|
|
||||||
setPage(1);
|
|
||||||
readRegister(0x1F); // AIC31XX_HPDRIVER
|
|
||||||
readRegister(0x20); // AIC31XX_SPKAMP
|
|
||||||
readRegister(0x21); // AIC31XX_HPPOP
|
|
||||||
readRegister(0x22); // AIC31XX_SPPGARAMP
|
|
||||||
readRegister(0x23); // AIC31XX_DACMIXERROUTE
|
|
||||||
readRegister(0x24); // AIC31XX_LANALOGHPL
|
|
||||||
readRegister(0x25); // AIC31XX_RANALOGHPR
|
|
||||||
readRegister(0x26); // AIC31XX_LANALOGSPL
|
|
||||||
readRegister(0x27); // AIC31XX_RANALOGSPR
|
|
||||||
readRegister(0x28); // AIC31XX_HPLGAIN
|
|
||||||
readRegister(0x29); // AIC31XX_HPRGAIN
|
|
||||||
readRegister(0x2A); // AIC31XX_SPLGAIN
|
|
||||||
readRegister(0x2B); // AIC31XX_SPRGAIN
|
|
||||||
readRegister(0x2C); // AIC31XX_HPCONTROL
|
|
||||||
readRegister(0x2E); // AIC31XX_MICBIAS
|
|
||||||
readRegister(0x2F); // AIC31XX_MICPGA
|
|
||||||
readRegister(0x30); // AIC31XX_MICPGAPI
|
|
||||||
readRegister(0x31); // AIC31XX_MICPGAMI
|
|
||||||
readRegister(0x32); // AIC31XX_MICPGACM
|
|
||||||
|
|
||||||
setPage(3);
|
|
||||||
readRegister(0x10); // AIC31XX_TIMERDIVIDER
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct audio_format *output_format = audio_i2s_setup(&audio_format, &config);
|
|
||||||
assert(output_format);
|
|
||||||
if (!output_format) {
|
|
||||||
panic("PicoAudio: Unable to open audio device.\n");
|
|
||||||
}
|
|
||||||
assert(producer_pool);
|
|
||||||
bool ok = audio_i2s_connect(producer_pool);
|
|
||||||
assert(ok);
|
|
||||||
audio_i2s_set_enabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void i2s_audio_handle_buffer(void) {
|
|
||||||
audio_buffer *buffer = take_audio_buffer(producer_pool, true);
|
|
||||||
fillsamples(reinterpret_cast<audio_sample*>(buffer->buffer->bytes), buffer->max_sample_count);
|
|
||||||
buffer->sample_count = buffer->max_sample_count;
|
|
||||||
give_audio_buffer(producer_pool, buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void core1_func_tft() {
|
static void core1_func_tft() {
|
||||||
i2s_audio_init();
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (producer_pool && fillsamples) i2s_audio_handle_buffer();
|
if (fillsamples != NULL) pwm_audio_handle_buffer();
|
||||||
__dmb();
|
__dmb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PICO_DSP::begin_audio(int samplesize, void (*callback)(short * stream, int len))
|
void PICO_DSP::begin_audio(int samplesize, void (*callback)(short * stream, int len))
|
||||||
{
|
{
|
||||||
if (!callback) return;
|
|
||||||
|
|
||||||
producer_pool = audio_new_producer_pool(&producer_format, 3, samplesize);
|
|
||||||
fillsamples = callback;
|
|
||||||
multicore_launch_core1(core1_func_tft);
|
multicore_launch_core1(core1_func_tft);
|
||||||
|
pwm_audio_init(samplesize, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PICO_DSP::end_audio()
|
void PICO_DSP::end_audio()
|
||||||
|
|
@ -1588,7 +1485,8 @@ void PICO_DSP::end_audio()
|
||||||
|
|
||||||
void * PICO_DSP::get_buffer_audio(void)
|
void * PICO_DSP::get_buffer_audio(void)
|
||||||
{
|
{
|
||||||
return NULL; // not implemented
|
void *buf = audio_buffers[cur_audio_buffer==0?1:0];
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
BIN
MCUME_pico2/fatfs/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/fatfs/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -2,71 +2,40 @@
|
||||||
RP2350 flash driver
|
RP2350 flash driver
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "flash_t.h"
|
#include "flash_t.h"
|
||||||
|
|
||||||
#include "hardware/flash.h"
|
#include "hardware/flash.h"
|
||||||
#include "hardware/sync.h"
|
#include "hardware/sync.h"
|
||||||
#include "emuapi.h"
|
#include "emuapi.h"
|
||||||
|
|
||||||
extern size_t _psram_size;
|
|
||||||
|
|
||||||
static bool using_psram;
|
|
||||||
|
|
||||||
#define PSRAM_BASE (0x11000000)
|
|
||||||
// #define PSRAM_BASE (0x15000000) // there's no reason to use uncached access
|
|
||||||
|
|
||||||
unsigned char * flash_start = (unsigned char *)(XIP_BASE + HW_FLASH_STORAGE_BASE);
|
unsigned char * flash_start = (unsigned char *)(XIP_BASE + HW_FLASH_STORAGE_BASE);
|
||||||
unsigned char * flash_end = (unsigned char *)(XIP_BASE + HW_FLASH_STORAGE_TOP);
|
unsigned char * flash_end = (unsigned char *)(XIP_BASE + HW_FLASH_STORAGE_TOP);
|
||||||
|
|
||||||
static uint8_t cache[FLASH_SECTOR_SIZE];
|
static uint8_t cache[FLASH_SECTOR_SIZE];
|
||||||
|
|
||||||
static void flash_setup() {
|
int flash_load(const char * filename)
|
||||||
if (_psram_size) {
|
|
||||||
using_psram = true;
|
|
||||||
flash_start = (unsigned char*)PSRAM_BASE;
|
|
||||||
flash_end = flash_start + _psram_size;
|
|
||||||
} else {
|
|
||||||
using_psram = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int flash_load_common(const char * filename, bool do_bswap)
|
|
||||||
{
|
{
|
||||||
flash_setup();
|
uint32_t offset = HW_FLASH_STORAGE_BASE;
|
||||||
|
|
||||||
uint8_t *dest = flash_start;
|
|
||||||
int n;
|
int n;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
emu_printf("flash_load...");
|
emu_printf("flash_load...");
|
||||||
int f = emu_FileOpen(filename,"r+b");
|
int f = emu_FileOpen(filename,"r+b");
|
||||||
if (f) {
|
if (f) {
|
||||||
while ( (dest < (flash_end-FLASH_SECTOR_SIZE)) && (n = emu_FileRead(cache,FLASH_SECTOR_SIZE,f) ) ) {
|
while ( (offset < (HW_FLASH_STORAGE_TOP-FLASH_SECTOR_SIZE)) && (n = emu_FileRead(cache,FLASH_SECTOR_SIZE,f) ) ) {
|
||||||
if (do_bswap) {
|
//memcpy(cache, (unsigned char *)offset, n);
|
||||||
for (int i=0;i<n; i+=2) {
|
uint32_t ints = save_and_disable_interrupts();
|
||||||
uint8_t k = cache[i];
|
flash_range_erase(offset, FLASH_SECTOR_SIZE);
|
||||||
cache[i]=cache[i+1];
|
flash_range_program(offset, (const uint8_t *)&cache[0], FLASH_SECTOR_SIZE);
|
||||||
cache[i+1] = k;
|
restore_interrupts(ints);
|
||||||
}
|
emu_printi(n);
|
||||||
}
|
emu_printi(offset);
|
||||||
if (using_psram) {
|
//uint8_t * pt = (uint8_t*)(XIP_BASE + offset);
|
||||||
memcpy(dest, cache, n);
|
//emu_printi(pt[0]);
|
||||||
} else if (memcmp(cache, dest, n)) {
|
//emu_printi(pt[1]);
|
||||||
uint32_t ints = save_and_disable_interrupts();
|
//emu_printi(pt[2]);
|
||||||
uint32_t offset = dest - (uint8_t*)XIP_BASE;
|
//emu_printi(pt[3]);
|
||||||
flash_range_erase(offset, FLASH_SECTOR_SIZE);
|
offset += FLASH_SECTOR_SIZE;
|
||||||
flash_range_program(offset, (const uint8_t *)&cache[0], FLASH_SECTOR_SIZE);
|
|
||||||
restore_interrupts(ints);
|
|
||||||
emu_printi(n);
|
|
||||||
emu_printi(offset);
|
|
||||||
//uint8_t * pt = (uint8_t*)(XIP_BASE + offset);
|
|
||||||
//emu_printi(pt[0]);
|
|
||||||
//emu_printi(pt[1]);
|
|
||||||
//emu_printi(pt[2]);
|
|
||||||
//emu_printi(pt[3]);
|
|
||||||
}
|
|
||||||
dest += FLASH_SECTOR_SIZE;
|
|
||||||
size += n;
|
size += n;
|
||||||
}
|
}
|
||||||
emu_FileClose(f);
|
emu_FileClose(f);
|
||||||
|
|
@ -76,20 +45,45 @@ int flash_load_common(const char * filename, bool do_bswap)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flash_load(const char * filename)
|
int flash_load_bswap(const char * filename)
|
||||||
{
|
{
|
||||||
return flash_load_common(filename, false);
|
uint32_t offset = HW_FLASH_STORAGE_BASE;
|
||||||
}
|
int n;
|
||||||
|
int size = 0;
|
||||||
|
emu_printf("flash_load...");
|
||||||
|
int f = emu_FileOpen(filename,"r+b");
|
||||||
|
if (f) {
|
||||||
|
while ( (offset < (HW_FLASH_STORAGE_TOP-FLASH_SECTOR_SIZE)) && (n = emu_FileRead(cache,FLASH_SECTOR_SIZE,f) ) ) {
|
||||||
|
for (int i=0;i<n; i+=2) {
|
||||||
|
uint8_t k = cache[i];
|
||||||
|
cache[i]=cache[i+1];
|
||||||
|
cache[i+1] = k;
|
||||||
|
}
|
||||||
|
//memcpy(cache, (unsigned char *)offset, n);
|
||||||
|
uint32_t ints = save_and_disable_interrupts();
|
||||||
|
flash_range_erase(offset, FLASH_SECTOR_SIZE);
|
||||||
|
flash_range_program(offset, (const uint8_t *)&cache[0], FLASH_SECTOR_SIZE);
|
||||||
|
restore_interrupts(ints);
|
||||||
|
emu_printi(n);
|
||||||
|
emu_printi(offset);
|
||||||
|
//uint8_t * pt = (uint8_t*)(XIP_BASE + offset);
|
||||||
|
//emu_printi(pt[0]);
|
||||||
|
//emu_printi(pt[1]);
|
||||||
|
//emu_printi(pt[2]);
|
||||||
|
//emu_printi(pt[3]);
|
||||||
|
offset += FLASH_SECTOR_SIZE;
|
||||||
|
size += n;
|
||||||
|
}
|
||||||
|
emu_FileClose(f);
|
||||||
|
emu_printf("flash_load OK.");
|
||||||
|
}
|
||||||
|
|
||||||
int flash_load_bswap(const char * filename)
|
return size;
|
||||||
{
|
|
||||||
return flash_load_common(filename, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int flash_verify(unsigned char * buf, int size)
|
int flash_verify(unsigned char * buf, int size)
|
||||||
{
|
{
|
||||||
flash_setup();
|
unsigned char * datapt = (unsigned char *)(XIP_BASE + HW_FLASH_STORAGE_BASE);
|
||||||
unsigned char * datapt = flash_start;
|
|
||||||
emu_printf("flash_verify...");
|
emu_printf("flash_verify...");
|
||||||
int count = size;
|
int count = size;
|
||||||
while (count++ < size) {
|
while (count++ < size) {
|
||||||
|
|
@ -105,4 +99,4 @@ int flash_verify(unsigned char * buf, int size)
|
||||||
}
|
}
|
||||||
emu_printf("flash_verify OK.");
|
emu_printf("flash_verify OK.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 53a61412565177133c810441f675a5d4a0bf24fa
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit bddd20f928ce76142793bef434d4f75f4af6e433
|
|
||||||
|
|
@ -46,7 +46,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(250000, true);
|
// set_sys_clock_khz(250000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(250000, true);
|
set_sys_clock_khz(250000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
|
||||||
BIN
MCUME_pico2/pico64/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/pico64/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -290,8 +290,8 @@ static uint8_t nbkeys = 0;
|
||||||
static uint8_t kcnt = 0;
|
static uint8_t kcnt = 0;
|
||||||
static bool toggle = true;
|
static bool toggle = true;
|
||||||
|
|
||||||
static const char * textseq;
|
static char * textseq;
|
||||||
static const char * textload = "LOAD\"\"\r\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tRUN\r";
|
static char * textload = "LOAD\"\"\r\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tRUN\r";
|
||||||
static char textkey[1];
|
static char textkey[1];
|
||||||
|
|
||||||
static bool res=false;
|
static bool res=false;
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,8 @@ const unsigned short key_map1[] = {
|
||||||
#define keylables_map2_2 (char *)" ()?/\"<>,: "
|
#define keylables_map2_2 (char *)" ()?/\"<>,: "
|
||||||
const unsigned short key_map2[] = {
|
const unsigned short key_map2[] = {
|
||||||
'1','2','3','4','5','6','7','8','9','0',0,
|
'1','2','3','4','5','6','7','8','9','0',0,
|
||||||
0, '!','@','#','$','%','+','&','*','-','/',
|
0, '!','@','#','$','%','+','&','*','-','\/',
|
||||||
0, '(',')','?','/','"','<','>',',',':',
|
0, '(',')','?','\/','"','<','>',',',':',
|
||||||
145,157,29,17 //U L R D
|
145,157,29,17 //U L R D
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(225000, true);
|
// set_sys_clock_khz(225000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(280000, true);
|
set_sys_clock_khz(280000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(250000, true);
|
// set_sys_clock_khz(250000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(250000, true);
|
set_sys_clock_khz(250000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
|
||||||
BIN
MCUME_pico2/pico8086/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/pico8086/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -42,7 +42,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(250000, true);
|
// set_sys_clock_khz(250000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(250000, true);
|
set_sys_clock_khz(250000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
@ -182,4 +182,4 @@ void emu_sndPlayBuzz(int size, int val) {
|
||||||
mymixer.buzz(size,val);
|
mymixer.buzz(size,val);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
BIN
MCUME_pico2/picocastaway/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/picocastaway/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -49,7 +49,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(250000, true);
|
// set_sys_clock_khz(250000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(250000, true);
|
set_sys_clock_khz(250000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(250000, true);
|
// set_sys_clock_khz(250000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(250000, true);
|
set_sys_clock_khz(250000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
|
||||||
BIN
MCUME_pico2/picogb/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/picogb/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -44,7 +44,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(250000, true);
|
// set_sys_clock_khz(250000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(250000, true);
|
set_sys_clock_khz(250000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
|
||||||
BIN
MCUME_pico2/picogen/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/picogen/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -19,8 +19,6 @@ __license__ = "GPLv3"
|
||||||
#ifndef _gwenesis_vdp_H_
|
#ifndef _gwenesis_vdp_H_
|
||||||
#define _gwenesis_vdp_H_
|
#define _gwenesis_vdp_H_
|
||||||
|
|
||||||
#include "stdint.h"
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define BIT(v, idx) (((v) >> (idx)) & 1)
|
#define BIT(v, idx) (((v) >> (idx)) & 1)
|
||||||
|
|
@ -153,4 +151,4 @@ void gwenesis_vdp_gfx_load_state();
|
||||||
void gwenesis_vdp_mem_save_state();
|
void gwenesis_vdp_mem_save_state();
|
||||||
void gwenesis_vdp_mem_load_state();
|
void gwenesis_vdp_mem_load_state();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -44,7 +44,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(250000, true);
|
// set_sys_clock_khz(250000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(280000, true);
|
set_sys_clock_khz(280000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
@ -175,7 +175,7 @@ void emu_sndInit() {
|
||||||
|
|
||||||
void * emu_sndGetBuffer(void)
|
void * emu_sndGetBuffer(void)
|
||||||
{
|
{
|
||||||
panic("not implemented");
|
return tft.get_buffer_audio();
|
||||||
}
|
}
|
||||||
|
|
||||||
void emu_sndPlaySound(int chan, int volume, int freq)
|
void emu_sndPlaySound(int chan, int volume, int freq)
|
||||||
|
|
|
||||||
BIN
MCUME_pico2/picomsx/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/picomsx/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -1,4 +1,3 @@
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "emuapi.h"
|
#include "emuapi.h"
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(250000, true);
|
// set_sys_clock_khz(250000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(250000, true);
|
set_sys_clock_khz(250000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
@ -58,7 +58,7 @@ int main(void) {
|
||||||
vreg_set_voltage(VREG_VOLTAGE_1_40);
|
vreg_set_voltage(VREG_VOLTAGE_1_40);
|
||||||
sleep_ms(10);
|
sleep_ms(10);
|
||||||
*qmi_m0_timing = 0x60007204;
|
*qmi_m0_timing = 0x60007204;
|
||||||
set_sys_clock_khz(120000, false);
|
set_sys_clock_khz(140000, false);
|
||||||
*qmi_m0_timing = 0x60007303;
|
*qmi_m0_timing = 0x60007303;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(250000, true);
|
// set_sys_clock_khz(250000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(250000, true);
|
set_sys_clock_khz(250000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
|
||||||
BIN
MCUME_pico2/picopce/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/picopce/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -44,7 +44,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(250000, true);
|
// set_sys_clock_khz(250000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(250000, true);
|
set_sys_clock_khz(250000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
|
||||||
BIN
MCUME_pico2/picosms/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/picosms/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -50,7 +50,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(250000, true);
|
// set_sys_clock_khz(250000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(250000, true);
|
set_sys_clock_khz(250000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(250000, true);
|
// set_sys_clock_khz(250000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(250000, true);
|
set_sys_clock_khz(250000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ int main(void) {
|
||||||
// set_sys_clock_khz(225000, true);
|
// set_sys_clock_khz(225000, true);
|
||||||
|
|
||||||
#ifdef HAS_USBPIO
|
#ifdef HAS_USBPIO
|
||||||
set_sys_clock_khz(120000, true);
|
set_sys_clock_khz(140000, true);
|
||||||
#else
|
#else
|
||||||
set_sys_clock_khz(250000, true);
|
set_sys_clock_khz(250000, true);
|
||||||
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
*((uint32_t *)(0x40010000+0x58)) = 2 << 16; //CLK_HSTX_DIV = 2 << 16; // HSTX clock/2
|
||||||
|
|
|
||||||
BIN
MCUME_pico2/sd_driver/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/sd_driver/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -118,7 +118,7 @@
|
||||||
// Size of buffer to hold descriptors and other data used for enumeration
|
// Size of buffer to hold descriptors and other data used for enumeration
|
||||||
#define CFG_TUH_ENUMERATION_BUFSIZE 256
|
#define CFG_TUH_ENUMERATION_BUFSIZE 256
|
||||||
|
|
||||||
#define CFG_TUH_HUB 1
|
#define CFG_TUH_HUB 0
|
||||||
#define CFG_TUH_CDC 0
|
#define CFG_TUH_CDC 0
|
||||||
#define CFG_TUH_HID 4 // typical keyboard + mouse device can have 3-4 HID interfaces
|
#define CFG_TUH_HID 4 // typical keyboard + mouse device can have 3-4 HID interfaces
|
||||||
#define CFG_TUH_MSC 0
|
#define CFG_TUH_MSC 0
|
||||||
|
|
|
||||||
BIN
MCUME_pico2/usb_kbd/.DS_Store
vendored
Normal file
BIN
MCUME_pico2/usb_kbd/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -27,7 +27,6 @@
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#include "kbd.h"
|
#include "kbd.h"
|
||||||
#include "platform_config.h"
|
#include "platform_config.h"
|
||||||
#include "display/emuapi.h"
|
|
||||||
|
|
||||||
/* ================== Keycode translation table. ==================== */
|
/* ================== Keycode translation table. ==================== */
|
||||||
|
|
||||||
|
|
@ -373,52 +372,7 @@ static void process_kbd_report (hid_keyboard_report_t const *report)
|
||||||
}
|
}
|
||||||
prev_report = *report;
|
prev_report = *report;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_gamepad_report(const uint8_t *report) {
|
|
||||||
uint16_t decoded_report = 0;
|
|
||||||
|
|
||||||
// Directional Controls
|
|
||||||
// Left is when byte 2 is close to 0x00
|
|
||||||
if (report[0] < 0x40) {
|
|
||||||
decoded_report |= MASK_JOY2_RIGHT; // Note: swapped due to gameboy mapping
|
|
||||||
}
|
|
||||||
// Right is when byte 2 is close to 0xFF
|
|
||||||
if (report[0] > 0xB0) {
|
|
||||||
decoded_report |= MASK_JOY2_LEFT; // Note: swapped due to gameboy mapping
|
|
||||||
}
|
|
||||||
// Up is when byte 1 is close to 0x00
|
|
||||||
if (report[1] < 0x40) {
|
|
||||||
decoded_report |= MASK_JOY2_UP;
|
|
||||||
}
|
|
||||||
// Down is when byte 1 is close to 0xFF
|
|
||||||
if (report[1] > 0xB0) {
|
|
||||||
decoded_report |= MASK_JOY2_DOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Button (check for 0x2F or 0x1F in byte 6)
|
|
||||||
if ((report[5] & 0x20) || (report[5] & 0x10)) {
|
|
||||||
decoded_report |= MASK_KEY_USER3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// B Button (check for 0x4F or 0x8F in byte 6)
|
|
||||||
if ((report[5] & 0x40) || (report[5] & 0x80)) {
|
|
||||||
decoded_report |= MASK_JOY2_BTN;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select Button (byte 7, bit 0x10)
|
|
||||||
if (report[6] & 0x10) {
|
|
||||||
decoded_report |= MASK_KEY_USER1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start Button (byte 7, bit 0x20)
|
|
||||||
if (report[6] & 0x20) {
|
|
||||||
decoded_report |= MASK_KEY_USER2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the decoded gamepad state
|
|
||||||
kbd_signal_raw_gamepad(decoded_report);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
@ -453,10 +407,8 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
|
||||||
{
|
{
|
||||||
printf("Keyboard found\n");
|
printf("Keyboard found\n");
|
||||||
tuh_hid_receive_report (dev_addr, instance);
|
tuh_hid_receive_report (dev_addr, instance);
|
||||||
} else {
|
|
||||||
printf("not a keyboard found (but asking for reports anyway!)\n");
|
|
||||||
tuh_hid_receive_report (dev_addr, instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when device with hid interface is un-mounted
|
// Invoked when device with hid interface is un-mounted
|
||||||
|
|
@ -474,25 +426,11 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons
|
||||||
// In principle we don't need to test that this USB report came from
|
// In principle we don't need to test that this USB report came from
|
||||||
// a keyboard, since we are only asking for reports from keyboards.
|
// a keyboard, since we are only asking for reports from keyboards.
|
||||||
// But, for future expansion, we should be systematic
|
// But, for future expansion, we should be systematic
|
||||||
int proto = tuh_hid_interface_protocol (dev_addr, instance);
|
switch (tuh_hid_interface_protocol (dev_addr, instance))
|
||||||
switch (proto)
|
|
||||||
{
|
{
|
||||||
case HID_ITF_PROTOCOL_KEYBOARD:
|
case HID_ITF_PROTOCOL_KEYBOARD:
|
||||||
process_kbd_report ((hid_keyboard_report_t const*) report);
|
process_kbd_report ((hid_keyboard_report_t const*) report);
|
||||||
break;
|
break;
|
||||||
case HID_ITF_PROTOCOL_NONE:
|
|
||||||
if (len >= 8) {
|
|
||||||
process_gamepad_report(report);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#if 0 // you get to implement it, hoss!
|
|
||||||
case HID_ITF_PROTOCOL_MOUSE:
|
|
||||||
printf("MOUSE len=%d\n", len);
|
|
||||||
if (len >= 6) {
|
|
||||||
process_mouse_report (len, report);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ask the device for the next report -- asking for a report is a
|
// Ask the device for the next report -- asking for a report is a
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define KBD_FLAG_LSHIFT 0x01
|
#define KBD_FLAG_LSHIFT 0x01
|
||||||
#define KBD_FLAG_LCONTROL 0x02
|
#define KBD_FLAG_LCONTROL 0x02
|
||||||
#define KBD_FLAG_LALT 0x04
|
#define KBD_FLAG_LALT 0x04
|
||||||
|
|
@ -50,7 +48,6 @@ extern "C" {
|
||||||
* or released. */
|
* or released. */
|
||||||
extern void kbd_signal_raw_key(int keycode, int code, int codeshifted, int flags, int pressed);
|
extern void kbd_signal_raw_key(int keycode, int code, int codeshifted, int flags, int pressed);
|
||||||
extern void kbd_set_locale(KLAYOUT layout);
|
extern void kbd_set_locale(KLAYOUT layout);
|
||||||
extern void kbd_signal_raw_gamepad(uint16_t new_pad_state);
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -255,7 +255,7 @@ Game console systems supported and status on various MCU platforms<br>
|
||||||
- "5200" => for atari5200, put your Atari 5200 roms here (.bin)
|
- "5200" => for atari5200, put your Atari 5200 roms here (.bin)
|
||||||
- "800" => for atari800, put your Atari 800 cartridges here (.rom)
|
- "800" => for atari800, put your Atari 800 cartridges here (.rom)
|
||||||
- 'c64" => for c64, put your C64 programs here (.prg), with sub-dirs or not
|
- 'c64" => for c64, put your C64 programs here (.prg), with sub-dirs or not
|
||||||
- "v20" => for VIC20, put your V20 programs (.prg), with sub-dirs or not
|
- "vic20" => for VIC20, put your V20 programs (.prg), with sub-dirs or not
|
||||||
- "apple2" => for Apple2 disks, put your ".dsk" files here, with sub-dirs or not
|
- "apple2" => for Apple2 disks, put your ".dsk" files here, with sub-dirs or not
|
||||||
- "o2em" => for odyssey/videopac, put your Videopac/Odysssey roms here (.bin)
|
- "o2em" => for odyssey/videopac, put your Videopac/Odysssey roms here (.bin)
|
||||||
- "coleco" => for colem, put your Colecovision roms here (.rom, including coleco.rom)
|
- "coleco" => for colem, put your Colecovision roms here (.rom, including coleco.rom)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue