├── .gitattributes ├── .github └── workflows │ ├── release.yml │ └── test.yml ├── .gitignore ├── .gitmodules ├── .vscode ├── c_cpp_properties.json ├── launch.json ├── settings.json └── tasks.json ├── CMakeLists.txt ├── LICENSE.md ├── README.md ├── build.sh ├── build_tests.sh ├── formatted_storage.bin ├── images ├── Dreamcast_Port.png ├── Dreamcast_Screen_Words.png ├── Frame_Word.png ├── Isolation_Circuitry.png ├── Isolation_Circuitry_Option_1.png ├── Isolation_Circuitry_Option_2.png ├── MapleBus_Class_State_Machine.png ├── Maple_Bus_Clocking_Phases.png ├── Maple_Bus_Electronics_Block_Diagram.png ├── Maple_Bus_End_Sequence.png ├── Maple_Bus_Hardware_Communication.png ├── Maple_Bus_Start_Sequence.png ├── Maple_Bus_Start_and_End_Sequences.png ├── Maple_Bus_State_Truth_Table.png ├── client-schematic.png ├── client_mode_sm.gif ├── host_mode_sm.gif └── schematic.png ├── inc ├── GamepadHost.hpp ├── VibrationObserver.hpp ├── configuration.h ├── dreamcast_constants.h ├── dreamcast_structures.h ├── global_constants.h ├── hal │ ├── MapleBus │ │ ├── MapleBusInterface.hpp │ │ └── MaplePacket.hpp │ ├── System │ │ ├── ClockInterface.hpp │ │ ├── LockGuard.hpp │ │ ├── MutexInterface.hpp │ │ ├── SystemIdentification.hpp │ │ └── SystemMemory.hpp │ └── Usb │ │ ├── CommandParser.hpp │ │ ├── DreamcastControllerObserver.hpp │ │ ├── TtyParser.hpp │ │ ├── UsbFile.hpp │ │ ├── UsbFileSystem.hpp │ │ ├── client_usb_interface.hpp │ │ ├── host_usb_interface.hpp │ │ └── usb_interface.hpp └── utils.h ├── measurements ├── Dreamcast-Power-Up-Digital-and-Analog-Player1-Controller-VMU-JumpPack.sal ├── README.md ├── maple bus test 1.sal ├── maple bus test 2.sal ├── maple bus test 3.sal ├── maple bus test 4.sal ├── maple bus test 5.sal └── maple bus test 6.sal ├── pcb ├── CAMOutputs │ ├── Assembly │ │ ├── DreamPicoPortSchem.txt │ │ ├── PnP_DreamPicoPortSchem_back.txt │ │ └── PnP_DreamPicoPortSchem_front.txt │ ├── DrillFiles │ │ └── drill_1_16.xln │ └── GerberFiles │ │ ├── copper_bottom.gbr │ │ ├── copper_top.gbr │ │ ├── gerber_job.gbrjob │ │ ├── profile.gbr │ │ ├── silkscreen_bottom.gbr │ │ ├── silkscreen_top.gbr │ │ ├── soldermask_bottom.gbr │ │ ├── soldermask_top.gbr │ │ ├── solderpaste_bottom.gbr │ │ └── solderpaste_top.gbr ├── DreamPicoPortSchem.3mf ├── DreamPicoPortSchem.brd ├── DreamPicoPortSchem.cam ├── DreamPicoPortSchem.sch ├── acknowledgements.txt ├── board-bottom.png ├── board-examples.jpg └── board-top.png ├── run_tests.sh ├── scripts ├── a.bmp ├── b.bmp ├── c.bmp ├── cmd2img.py ├── d.bmp └── img2cmd.py ├── src ├── CMakeLists.txt ├── clientLib │ ├── CMakeLists.txt │ ├── DreamcastController.cpp │ ├── DreamcastController.hpp │ ├── DreamcastKeyboard.hpp │ ├── DreamcastMainPeripheral.cpp │ ├── DreamcastMainPeripheral.hpp │ ├── DreamcastPeripheral.cpp │ ├── DreamcastPeripheral.hpp │ ├── DreamcastPeripheralFunction.hpp │ ├── DreamcastScreen.cpp │ ├── DreamcastScreen.hpp │ ├── DreamcastStorage.cpp │ ├── DreamcastStorage.hpp │ ├── DreamcastTimer.cpp │ ├── DreamcastTimer.hpp │ ├── DreamcastVibration.hpp │ └── README.md ├── hal │ ├── CMakeLists.txt │ ├── MapleBus │ │ ├── CMakeLists.txt │ │ ├── MapleBus.cpp │ │ ├── MapleBus.hpp │ │ ├── PioProgram.hpp │ │ ├── maple_in.pio │ │ └── maple_out.pio │ ├── System │ │ ├── CMakeLists.txt │ │ ├── Clock.cpp │ │ ├── Clock.hpp │ │ ├── CriticalSectionMutex.cpp │ │ ├── CriticalSectionMutex.hpp │ │ ├── Mutex.cpp │ │ ├── Mutex.hpp │ │ ├── NonVolatilePicoSystemMemory.cpp │ │ ├── NonVolatilePicoSystemMemory.hpp │ │ ├── PassiveBuzzer.cpp │ │ ├── PassiveBuzzer.hpp │ │ ├── PicoIdentification.cpp │ │ ├── PicoIdentification.hpp │ │ ├── VolatileSystemMemory.cpp │ │ └── VolatileSystemMemory.hpp │ └── Usb │ │ ├── CMakeLists.txt │ │ ├── Client │ │ ├── CMakeLists.txt │ │ ├── UsbControllerDevice.cpp │ │ ├── UsbControllerDevice.h │ │ ├── UsbGamepad.cpp │ │ ├── UsbGamepad.h │ │ ├── UsbGamepadDreamcastControllerObserver.cpp │ │ ├── UsbGamepadDreamcastControllerObserver.hpp │ │ ├── cdc.cpp │ │ ├── cdc.hpp │ │ ├── msc_disk.cpp │ │ ├── msc_disk.hpp │ │ ├── tusb_config.h │ │ ├── usb_descriptors.c │ │ ├── usb_descriptors.h │ │ └── usb_execution.cpp │ │ └── Host │ │ ├── CMakeLists.txt │ │ ├── Dualshock4Handler.hpp │ │ ├── HidHandler.hpp │ │ ├── hid_app.cpp │ │ ├── hid_app.hpp │ │ ├── tusb_config.h │ │ ├── usb_execution.cpp │ │ └── usb_host.cpp ├── hostLib │ ├── CMakeLists.txt │ ├── DreamcastMainNode.cpp │ ├── DreamcastMainNode.hpp │ ├── DreamcastNode.hpp │ ├── DreamcastSubNode.cpp │ ├── DreamcastSubNode.hpp │ ├── EndpointTxScheduler.cpp │ ├── EndpointTxScheduler.hpp │ ├── EndpointTxSchedulerInterface.hpp │ ├── PlayerData.hpp │ ├── PrioritizedTxScheduler.cpp │ ├── PrioritizedTxScheduler.hpp │ ├── README.md │ ├── ScreenData.cpp │ ├── ScreenData.hpp │ ├── Transmission.hpp │ ├── TransmissionTimeliner.cpp │ ├── TransmissionTimeliner.hpp │ ├── Transmitter.hpp │ ├── parsers │ │ ├── FlycastCommandParser.cpp │ │ ├── FlycastCommandParser.hpp │ │ ├── MaplePassthroughCommandParser.cpp │ │ ├── MaplePassthroughCommandParser.hpp │ │ ├── SerialStreamParser.cpp │ │ └── SerialStreamParser.hpp │ ├── peripherals │ │ ├── DreamcastArGun.cpp │ │ ├── DreamcastArGun.hpp │ │ ├── DreamcastCamera.cpp │ │ ├── DreamcastCamera.hpp │ │ ├── DreamcastController.cpp │ │ ├── DreamcastController.hpp │ │ ├── DreamcastExMedia.cpp │ │ ├── DreamcastExMedia.hpp │ │ ├── DreamcastGun.cpp │ │ ├── DreamcastGun.hpp │ │ ├── DreamcastKeyboard.cpp │ │ ├── DreamcastKeyboard.hpp │ │ ├── DreamcastMicrophone.cpp │ │ ├── DreamcastMicrophone.hpp │ │ ├── DreamcastMouse.cpp │ │ ├── DreamcastMouse.hpp │ │ ├── DreamcastPeripheral.hpp │ │ ├── DreamcastScreen.cpp │ │ ├── DreamcastScreen.hpp │ │ ├── DreamcastStorage.cpp │ │ ├── DreamcastStorage.hpp │ │ ├── DreamcastTimer.cpp │ │ ├── DreamcastTimer.hpp │ │ ├── DreamcastVibration.cpp │ │ └── DreamcastVibration.hpp │ └── test │ │ ├── CMakeLists.txt │ │ ├── MainNodeTests.cpp │ │ ├── MaplePacketTests.cpp │ │ ├── PrioritizedTxSchedulerTests.cpp │ │ ├── SerialStreamParserTests.cpp │ │ ├── SubNodeTests.cpp │ │ └── mocks │ │ ├── MockClock.hpp │ │ ├── MockCommandParser.hpp │ │ ├── MockDreamcastControllerObserver.hpp │ │ ├── MockDreamcastPeripheral.hpp │ │ ├── MockMapleBus.hpp │ │ ├── MockMutex.hpp │ │ └── MockUsbFileSystem.hpp ├── main │ ├── CMakeLists.txt │ ├── Client │ │ ├── CMakeLists.txt │ │ ├── I2cDevice.hpp │ │ ├── I2cDriver.cpp │ │ ├── I2cDriver.hpp │ │ ├── Ssd1309.cpp │ │ ├── Ssd1309.hpp │ │ ├── client_usb_host.cpp │ │ └── common │ │ │ ├── led.cpp │ │ │ └── led.hpp │ └── Host │ │ ├── CMakeLists.txt │ │ └── host.cpp └── test │ ├── CMakeLists.txt │ └── main.cpp └── very_clean.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Package release 2 | on: 3 | release: 4 | types: [created] 5 | jobs: 6 | deploy: 7 | runs-on: ubuntu-22.04 8 | defaults: 9 | run: 10 | shell: sh 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Install prerequisites 15 | run: sudo apt -y install gcc-arm-none-eabi build-essential 16 | - name: Install dependencies 17 | run: git submodule update --recursive --init 18 | - name: Build main package for pico 19 | run: ./build.sh pico 20 | - name: Build main package for pico2 21 | run: ./build.sh pico2 pico2 22 | - name: upload binaries to release 23 | uses: softprops/action-gh-release@v1 24 | if: ${{startsWith(github.ref, 'refs/tags/') }} 25 | with: 26 | files: dist/* 27 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-22.04 8 | defaults: 9 | run: 10 | shell: sh 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Install prerequisites 15 | run: sudo apt -y install gcc-arm-none-eabi build-essential 16 | - name: Install dependencies 17 | run: git submodule update --recursive --init 18 | - name: Build main package for pico 19 | run: ./build.sh pico 20 | - name: Build main package for pico2 21 | run: ./build.sh pico2 pico2 22 | - name: Build and run unit tests 23 | run: ./run_tests.sh 24 | - name: Save the test build 25 | uses: actions/upload-artifact@v4 26 | with: 27 | name: builds 28 | path: dist/* 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeCache.txt 2 | CMakeFiles/* 3 | build/* 4 | build-*/* 5 | build-test/* 6 | dist/* -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/pico-sdk"] 2 | path = ext/pico-sdk 3 | url = https://github.com/raspberrypi/pico-sdk.git 4 | -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Linux", 5 | "includePath": [ 6 | "${workspaceFolder}/ext/pico-sdk/**", 7 | "${workspaceFolder}/inc/**", 8 | "${workspaceFolder}/src/**" 9 | ], 10 | "defines": [], 11 | "compilerPath": "/usr/bin/gcc", 12 | "cStandard": "gnu17", 13 | "cppStandard": "c++17", 14 | "intelliSenseMode": "linux-gcc-x64", 15 | "configurationProvider": "ms-vscode.cmake-tools" 16 | } 17 | ], 18 | "version": 4 19 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Debug Test", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build-test/src/test/testExe", 12 | "args": [], 13 | "stopAtEntry": false, 14 | "cwd": "${workspaceFolder}", 15 | "environment": [], 16 | "externalConsole": false, 17 | "MIMode": "gdb", 18 | "miDebuggerPath": "/usr/bin/gdb", 19 | "setupCommands": [ 20 | { 21 | "description": "Enable pretty-printing for gdb", 22 | "text": "-enable-pretty-printing", 23 | "ignoreFailures": true 24 | } 25 | ], 26 | "preLaunchTask": "Build Tests" 27 | } 28 | ] 29 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "cctype": "cpp", 4 | "clocale": "cpp", 5 | "cmath": "cpp", 6 | "cstdbool": "cpp", 7 | "cstddef": "cpp", 8 | "cstdint": "cpp", 9 | "cstdio": "cpp", 10 | "cstdlib": "cpp", 11 | "ctime": "cpp", 12 | "cwchar": "cpp", 13 | "cwctype": "cpp", 14 | "array": "cpp", 15 | "atomic": "cpp", 16 | "bit": "cpp", 17 | "*.tcc": "cpp", 18 | "chrono": "cpp", 19 | "condition_variable": "cpp", 20 | "cstdarg": "cpp", 21 | "deque": "cpp", 22 | "unordered_map": "cpp", 23 | "vector": "cpp", 24 | "exception": "cpp", 25 | "algorithm": "cpp", 26 | "functional": "cpp", 27 | "iterator": "cpp", 28 | "memory": "cpp", 29 | "memory_resource": "cpp", 30 | "numeric": "cpp", 31 | "optional": "cpp", 32 | "random": "cpp", 33 | "ratio": "cpp", 34 | "string": "cpp", 35 | "string_view": "cpp", 36 | "system_error": "cpp", 37 | "tuple": "cpp", 38 | "type_traits": "cpp", 39 | "utility": "cpp", 40 | "fstream": "cpp", 41 | "initializer_list": "cpp", 42 | "iosfwd": "cpp", 43 | "istream": "cpp", 44 | "limits": "cpp", 45 | "mutex": "cpp", 46 | "new": "cpp", 47 | "ostream": "cpp", 48 | "sstream": "cpp", 49 | "stdexcept": "cpp", 50 | "streambuf": "cpp", 51 | "thread": "cpp", 52 | "cinttypes": "cpp", 53 | "typeinfo": "cpp", 54 | "list": "cpp", 55 | "map": "cpp", 56 | "set": "cpp", 57 | "iostream": "cpp", 58 | "cstring": "cpp", 59 | "any": "cpp", 60 | "forward_list": "cpp", 61 | "unordered_set": "cpp", 62 | "iomanip": "cpp", 63 | "variant": "cpp", 64 | "printf.h": "c", 65 | "bitset": "cpp", 66 | "*.ipp": "cpp", 67 | "ranges": "cpp", 68 | "regex": "cpp", 69 | "valarray": "cpp", 70 | "compare": "cpp", 71 | "concepts": "cpp", 72 | "netfwd": "cpp", 73 | "numbers": "cpp", 74 | "shared_mutex": "cpp", 75 | "configuration.h": "c" 76 | }, 77 | "cmake.configureOnOpen": false 78 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "tasks": [ 3 | { 4 | "type": "shell", 5 | "label": "C/C++: g++ build active file", 6 | "command": "/usr/bin/g++", 7 | "args": [ 8 | "-fdiagnostics-color=always", 9 | "-g", 10 | "${file}", 11 | "-o", 12 | "${fileDirname}/${fileBasenameNoExtension}" 13 | ], 14 | "options": { 15 | "cwd": "${fileDirname}" 16 | }, 17 | "problemMatcher": [ 18 | "$gcc" 19 | ], 20 | "group": { 21 | "kind": "build", 22 | "isDefault": false 23 | }, 24 | "detail": "Task generated by Debugger." 25 | }, 26 | { 27 | "type": "shell", 28 | "label": "Build", 29 | "command": "./build.sh", 30 | "args": [], 31 | "options": { 32 | "cwd": "${workspaceFolder}" 33 | }, 34 | "problemMatcher": [], 35 | "group": { 36 | "kind": "build", 37 | "isDefault": true 38 | } 39 | }, 40 | { 41 | "type": "shell", 42 | "label": "Build Tests", 43 | "command": "./build_tests.sh", 44 | "args": [], 45 | "options": { 46 | "cwd": "${workspaceFolder}" 47 | }, 48 | "problemMatcher": [], 49 | "group": { 50 | "kind": "build", 51 | "isDefault": false 52 | } 53 | }, 54 | { 55 | "type": "shell", 56 | "label": "Run Tests", 57 | "command": "./run_tests.sh", 58 | "args": [], 59 | "options": { 60 | "cwd": "${workspaceFolder}" 61 | }, 62 | "problemMatcher": [], 63 | "group": { 64 | "kind": "test", 65 | "isDefault": true 66 | } 67 | } 68 | ], 69 | "version": "2.0.0" 70 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | if(NOT ENABLE_UNIT_TEST) 6 | # Have pico_sdk_import.cmake use the local SDK if it was pulled down; otherwise, use path at 7 | # PICO_SDK_PATH environment variable as specified within pico_sdk_import.cmake 8 | if (EXISTS "${CMAKE_SOURCE_DIR}/ext/pico-sdk/CMakeLists.txt") 9 | set(PICO_SDK_PATH "${CMAKE_SOURCE_DIR}/ext/pico-sdk/" CACHE INTERNAL PICO_SDK_PATH) 10 | message("Using local pico SDK at ('${PICO_SDK_PATH}')") 11 | endif () 12 | 13 | if (NOT DEFINED PICO_SDK_PATH AND NOT DEFINED ENV{PICO_SDK_PATH}) 14 | message(FATAL_ERROR "PICO_SDK_PATH not defined; either execute:\ngit submodule update --recursive --init\nor set PICO_SDK_PATH in environment") 15 | endif () 16 | 17 | include("${PICO_SDK_PATH}/external/pico_sdk_import.cmake") 18 | 19 | pico_sdk_init() 20 | else() 21 | add_definitions(-DUNITTEST) 22 | endif() 23 | 24 | project(DreamPicoPort) 25 | 26 | add_subdirectory(src) 27 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | https://github.com/OrangeFox86/DreamPicoPort 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # USAGE: 4 | # build.sh 5 | 6 | # Provide one of the following as argument to adjust platform 7 | # pico (default) 8 | # pico2 9 | 10 | FLAVOR=pico 11 | DIST_PREFIX= 12 | 13 | if [ $# -gt 0 ]; then 14 | FLAVOR=$1 15 | shift 16 | fi 17 | 18 | if [ $# -gt 0 ]; then 19 | DIST_PREFIX="${1}_" 20 | shift 21 | fi 22 | 23 | BUILD_DIR="build-${FLAVOR}" 24 | DIST_DIR="./dist" 25 | GCC="/usr/bin/arm-none-eabi-gcc" 26 | GPP="/usr/bin/arm-none-eabi-g++" 27 | 28 | # Force the elf and uf2 binary files to always be regenerated on build 29 | # (this is so old uf2 files don't pile up in dist directory) 30 | rm ${BUILD_DIR}/src/*/*/*.elf 31 | rm ${BUILD_DIR}/src/*/*/*.uf2 32 | 33 | cmake \ 34 | --no-warn-unused-cli \ 35 | -DPICO_BOARD=${FLAVOR} \ 36 | -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE \ 37 | -DCMAKE_BUILD_TYPE:STRING=Release \ 38 | -DCMAKE_C_COMPILER:FILEPATH=${GCC} \ 39 | -DCMAKE_CXX_COMPILER:FILEPATH=${GPP} \ 40 | -DDREAMCAST_CONTROLLER_USB_PICO_TEST:BOOL=FALSE \ 41 | -S. \ 42 | -B./${BUILD_DIR} \ 43 | -G "Unix Makefiles" \ 44 | 45 | STATUS=$? 46 | if [ $STATUS -ne 0 ]; then 47 | echo "CMake returned error exit code: ${STATUS}" 48 | echo "Exiting" 49 | exit $STATUS 50 | fi 51 | 52 | cmake \ 53 | --build ${BUILD_DIR} \ 54 | --config Release \ 55 | --target all \ 56 | -j 10 \ 57 | 58 | STATUS=$? 59 | if [ $STATUS -ne 0 ]; then 60 | echo "CMake returned error exit code: ${STATUS}" 61 | echo "Exiting" 62 | exit $STATUS 63 | fi 64 | 65 | mkdir -p ${DIST_DIR} 66 | for file in ${BUILD_DIR}/src/*/*/*.uf2 67 | do 68 | filename=$(basename $file) 69 | cp -v -- "$file" "${DIST_DIR}/${DIST_PREFIX}${filename}" 70 | done 71 | -------------------------------------------------------------------------------- /build_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export BUILD_DIR="build-test" 4 | GCC="/usr/bin/gcc" 5 | GPP="/usr/bin/g++" 6 | 7 | cmake \ 8 | --no-warn-unused-cli \ 9 | -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE \ 10 | -DCMAKE_BUILD_TYPE:STRING=Debug \ 11 | -DCMAKE_C_COMPILER:FILEPATH=${GCC} \ 12 | -DCMAKE_CXX_COMPILER:FILEPATH=${GPP} \ 13 | -DENABLE_UNIT_TEST:BOOL=TRUE \ 14 | -S. \ 15 | -B./${BUILD_DIR} \ 16 | -G "Unix Makefiles" \ 17 | 18 | STATUS=$? 19 | if [ $STATUS -ne 0 ]; then 20 | echo "CMake returned error exit code: ${STATUS}" 21 | echo "Exiting" 22 | exit $STATUS 23 | fi 24 | 25 | cmake \ 26 | --build ${BUILD_DIR} \ 27 | --config Debug \ 28 | --target testExe \ 29 | -j 10 \ 30 | 31 | STATUS=$? 32 | if [ $STATUS -ne 0 ]; then 33 | echo "CMake returned error exit code: ${STATUS}" 34 | echo "Exiting" 35 | exit $STATUS 36 | fi 37 | -------------------------------------------------------------------------------- /formatted_storage.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/formatted_storage.bin -------------------------------------------------------------------------------- /images/Dreamcast_Port.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Dreamcast_Port.png -------------------------------------------------------------------------------- /images/Dreamcast_Screen_Words.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Dreamcast_Screen_Words.png -------------------------------------------------------------------------------- /images/Frame_Word.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Frame_Word.png -------------------------------------------------------------------------------- /images/Isolation_Circuitry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Isolation_Circuitry.png -------------------------------------------------------------------------------- /images/Isolation_Circuitry_Option_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Isolation_Circuitry_Option_1.png -------------------------------------------------------------------------------- /images/Isolation_Circuitry_Option_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Isolation_Circuitry_Option_2.png -------------------------------------------------------------------------------- /images/MapleBus_Class_State_Machine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/MapleBus_Class_State_Machine.png -------------------------------------------------------------------------------- /images/Maple_Bus_Clocking_Phases.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Maple_Bus_Clocking_Phases.png -------------------------------------------------------------------------------- /images/Maple_Bus_Electronics_Block_Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Maple_Bus_Electronics_Block_Diagram.png -------------------------------------------------------------------------------- /images/Maple_Bus_End_Sequence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Maple_Bus_End_Sequence.png -------------------------------------------------------------------------------- /images/Maple_Bus_Hardware_Communication.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Maple_Bus_Hardware_Communication.png -------------------------------------------------------------------------------- /images/Maple_Bus_Start_Sequence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Maple_Bus_Start_Sequence.png -------------------------------------------------------------------------------- /images/Maple_Bus_Start_and_End_Sequences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Maple_Bus_Start_and_End_Sequences.png -------------------------------------------------------------------------------- /images/Maple_Bus_State_Truth_Table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/Maple_Bus_State_Truth_Table.png -------------------------------------------------------------------------------- /images/client-schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/client-schematic.png -------------------------------------------------------------------------------- /images/client_mode_sm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/client_mode_sm.gif -------------------------------------------------------------------------------- /images/host_mode_sm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/host_mode_sm.gif -------------------------------------------------------------------------------- /images/schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/images/schematic.png -------------------------------------------------------------------------------- /inc/GamepadHost.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | 28 | class GamepadHost 29 | { 30 | public: 31 | inline GamepadHost() {} 32 | inline virtual ~GamepadHost() {} 33 | 34 | //! Enumerates hat positions 35 | enum class Hat : uint8_t 36 | { 37 | NEUTRAL = 0, 38 | UP, 39 | UP_RIGHT, 40 | RIGHT, 41 | DOWN_RIGHT, 42 | DOWN, 43 | DOWN_LEFT, 44 | LEFT, 45 | UP_LEFT 46 | }; 47 | 48 | //! Standard set of gamepad controls 49 | struct Controls 50 | { 51 | Hat hat; 52 | bool west; 53 | bool south; 54 | bool east; 55 | bool north; 56 | 57 | bool l1; 58 | bool r1; 59 | uint8_t l2; 60 | uint8_t r2; 61 | bool l3; 62 | bool r3; 63 | 64 | bool start; 65 | bool menu; 66 | 67 | uint8_t lx; 68 | uint8_t ly; 69 | uint8_t rx; 70 | uint8_t ry; 71 | }; 72 | 73 | //! Set updated controls 74 | //! @param[in] controls Updated controls 75 | virtual void setControls(const Controls& controls) = 0; 76 | }; 77 | 78 | void set_gamepad_host(GamepadHost* ctrlr); 79 | -------------------------------------------------------------------------------- /inc/VibrationObserver.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | 28 | class VibrationObserver 29 | { 30 | public: 31 | virtual ~VibrationObserver() {} 32 | 33 | //! Activate vibration 34 | //! @param[in] frequency The sine-wave frequency to vibrate 35 | //! @param[in] intensity Intensity between 0.0 and 1.0 36 | //! @param[in] inclination Inclination: -1 for ramp down, 0 for constant, 1 for ramp up 37 | //! @param[in] duration The total vibration duration in seconds; 0.0 means no stop duration 38 | //! specified 39 | virtual void vibrate(float frequency, float intensity, int8_t inclination, float duration) = 0; 40 | }; 41 | -------------------------------------------------------------------------------- /inc/dreamcast_constants.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | // Device functions 27 | #define DEVICE_FN_CONTROLLER 0x00000001 28 | #define DEVICE_FN_STORAGE 0x00000002 29 | #define DEVICE_FN_LCD 0x00000004 30 | #define DEVICE_FN_TIMER 0x00000008 31 | #define DEVICE_FN_AUDIO_INPUT 0x00000010 32 | #define DEVICE_FN_AR_GUN 0x00000020 33 | #define DEVICE_FN_KEYBOARD 0x00000040 34 | #define DEVICE_FN_GUN 0x00000080 35 | #define DEVICE_FN_VIBRATION 0x00000100 36 | #define DEVICE_FN_MOUSE 0x00000200 37 | #define DEVICE_FN_EXMEDIA 0x00000400 38 | #define DEVICE_FN_CAMERA 0x00000800 39 | 40 | //! Enumerates all of the valid commands for Dreamcast devices 41 | enum DreamcastCommand 42 | { 43 | COMMAND_DEVICE_INFO_REQUEST = 0x01, 44 | COMMAND_EXT_DEVICE_INFO_REQUEST = 0x02, 45 | COMMAND_RESET = 0x03, 46 | COMMAND_SHUTDOWN = 0x04, 47 | COMMAND_RESPONSE_DEVICE_INFO = 0x05, 48 | COMMAND_RESPONSE_EXT_DEVICE_INFO = 0x06, 49 | COMMAND_RESPONSE_ACK = 0x07, 50 | COMMAND_RESPONSE_DATA_XFER = 0x08, 51 | COMMAND_GET_CONDITION = 0x09, 52 | COMMAND_GET_MEMORY_INFORMATION = 0x0A, 53 | COMMAND_BLOCK_READ = 0x0B, 54 | COMMAND_BLOCK_WRITE = 0x0C, 55 | COMMAND_GET_LAST_ERROR = 0x0D, 56 | COMMAND_SET_CONDITION = 0x0E, 57 | COMMAND_RESPONSE_AR_ERROR = 0xF9, 58 | COMMAND_RESPONSE_LCD_ERROR = 0xFA, 59 | COMMAND_RESPONSE_FILE_ERROR = 0xFB, 60 | COMMAND_RESPONSE_REQUEST_RESEND = 0xFC, 61 | COMMAND_RESPONSE_UNKNOWN_COMMAND = 0xFD, 62 | COMMAND_RESPONSE_FUNCTION_CODE_NOT_SUPPORTED = 0xFE, 63 | COMMAND_INVALID = 0xFF 64 | }; 65 | 66 | #define EXPECTED_DEVICE_INFO_PAYLOAD_WORDS 28 -------------------------------------------------------------------------------- /inc/dreamcast_structures.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | 28 | //! Structure used to unpack an 8-byte controller condition package (little endian assumed) 29 | typedef struct controller_condition_s 30 | { 31 | uint8_t l; //!< 0: fully released; 255: fully pressed 32 | 33 | uint8_t r; //!< 0: fully released; 255: fully pressed 34 | 35 | // Digital bits: 36 | // 0: pressed 37 | // 1: released 38 | unsigned z:1; 39 | unsigned y:1; 40 | unsigned x:1; 41 | unsigned d:1; 42 | unsigned upb:1; 43 | unsigned downb:1; 44 | unsigned leftb:1; 45 | unsigned rightb:1; 46 | 47 | unsigned c:1; 48 | unsigned b:1; 49 | unsigned a:1; 50 | unsigned start:1; 51 | unsigned up:1; 52 | unsigned down:1; 53 | unsigned left:1; 54 | unsigned right:1; 55 | 56 | uint8_t rAnalogUD; //!< 0: up; 128: neutral; 255: down 57 | 58 | uint8_t rAnalogLR; //!< 0: up; 128: neutral; 255: down 59 | 60 | uint8_t lAnalogUD; //!< 0: up; 128: neutral; 255: down 61 | 62 | uint8_t lAnalogLR; //!< 0: left; 128: neutral; 255: right 63 | }__attribute__((packed)) controller_condition_t; 64 | 65 | #define NEUTRAL_CONTROLLER_CONDITION {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 128, 128, 128, 128} 66 | 67 | //! Button condition bits found in the VMU timer function (least significant byte) 68 | typedef struct vmu_timer_condition_s 69 | { 70 | // Digital bits: 71 | // 0: pressed 72 | // 1: released 73 | unsigned up:1; 74 | unsigned down:1; 75 | unsigned left:1; 76 | unsigned right:1; 77 | unsigned a:1; 78 | unsigned b:1; 79 | unsigned c:1; 80 | unsigned start:1; 81 | } __attribute__((packed)) vmu_timer_condition_t; 82 | 83 | #define NEUTRAL_VMU_TIMER_CONDITION {1, 1, 1, 1, 1, 1, 1, 1} 84 | -------------------------------------------------------------------------------- /inc/global_constants.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __GLOBAL_CONSTANTS_H__ 25 | #define __GLOBAL_CONSTANTS_H__ 26 | 27 | // These are just here to spell out the value being used 28 | #define MILLISECONDS_PER_SECOND 1000 29 | #define MICROSECONDS_PER_MILLISECOND 1000 30 | #define MICROSECONDS_PER_SECOND (MILLISECONDS_PER_SECOND * MICROSECONDS_PER_MILLISECOND) 31 | 32 | #endif // __GLOBAL_CONSTANTS_H__ 33 | -------------------------------------------------------------------------------- /inc/hal/System/ClockInterface.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __CLOCK_INTERFACE_H__ 25 | #define __CLOCK_INTERFACE_H__ 26 | 27 | #include 28 | 29 | class ClockInterface 30 | { 31 | public: 32 | virtual ~ClockInterface() {} 33 | virtual uint64_t getTimeUs() const = 0; 34 | }; 35 | 36 | #endif // __CLOCK_INTERFACE_H__ 37 | -------------------------------------------------------------------------------- /inc/hal/System/LockGuard.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __LOCK_GUARD_H__ 25 | #define __LOCK_GUARD_H__ 26 | 27 | #include 28 | #include "MutexInterface.hpp" 29 | 30 | //! This class is similar to std::lock_guard, but it is specifically meant to be used with 31 | //! MutexInterface. The special thing with MutexInterface is that doing a blocking lock has the 32 | //! potential to cause a deadlock (because spin lock is used, and there is no way to yield from IRQ 33 | //! context). As such, the functionality using the mutex must check this and perform necessary 34 | //! operations (even if it's just to log an error and spin forever). 35 | class LockGuard 36 | { 37 | public: 38 | LockGuard() = delete; 39 | 40 | //! Initializes data and locks mutex as long as it wouldn't cause a deadlock 41 | inline LockGuard(MutexInterface& mutex, bool allowDeadlock = false) : 42 | mMutex(mutex), 43 | mIsLocked(false) 44 | { 45 | if (allowDeadlock) 46 | { 47 | mMutex.lock(); 48 | mIsLocked = true; 49 | } 50 | else 51 | { 52 | int8_t lockValue = mMutex.tryLock(); 53 | if (lockValue == 0) 54 | { 55 | mMutex.lock(); 56 | mIsLocked = true; 57 | } 58 | else if (lockValue > 0) 59 | { 60 | mIsLocked = true; 61 | } 62 | // Else: not locked, would cause deadlock - due to simultaneous IRQ access on same core 63 | } 64 | } 65 | 66 | //! Unlocks mutex if it was previously locked 67 | virtual inline ~LockGuard() 68 | { 69 | if (mIsLocked) 70 | { 71 | mMutex.unlock(); 72 | } 73 | } 74 | 75 | //! @returns true iff the mutex was successfully locked in the constructor or false if 76 | //! locking would cause a deadlock 77 | inline bool isLocked() 78 | { 79 | return mIsLocked; 80 | } 81 | 82 | private: 83 | MutexInterface& mMutex; 84 | bool mIsLocked; 85 | }; 86 | 87 | #endif // __LOCK_GUARD_H__ 88 | -------------------------------------------------------------------------------- /inc/hal/System/MutexInterface.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __MUTEX_INTERFACE_H__ 25 | #define __MUTEX_INTERFACE_H__ 26 | 27 | #include 28 | 29 | //! This interface is used to decouple mutex functionality in HAL from the Dreamcast functionality. 30 | class MutexInterface 31 | { 32 | public: 33 | //! Constructor 34 | MutexInterface() {} 35 | 36 | //! Virtual destructor 37 | virtual ~MutexInterface() {} 38 | 39 | //! Blocks until mutex is available and then takes it 40 | virtual void lock() = 0; 41 | 42 | //! Releases the previously locked mutex 43 | virtual void unlock() = 0; 44 | 45 | //! Tries to obtain mutex without blocking 46 | //! @returns 1 if mutex was obtained 47 | //! @returns 0 if mutex was not obtained, and blocking would be valid in this context 48 | //! @returns -1 if mutex was not obtained, and blocking would cause deadlock 49 | virtual int8_t tryLock() = 0; 50 | }; 51 | 52 | #endif // __MUTEX_INTERFACE_H__ 53 | -------------------------------------------------------------------------------- /inc/hal/System/SystemIdentification.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class SystemIdentification 5 | { 6 | public: 7 | virtual ~SystemIdentification() = default; 8 | virtual std::uint32_t getSerialSize() = 0; 9 | virtual void getSerial(char* buffer, std::uint32_t bufflen) = 0; 10 | }; 11 | -------------------------------------------------------------------------------- /inc/hal/System/SystemMemory.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | 28 | class SystemMemory 29 | { 30 | public: 31 | //! Virtual destructor 32 | virtual ~SystemMemory() {} 33 | 34 | //! @returns number of bytes reserved in memory 35 | virtual uint32_t getMemorySize() = 0; 36 | 37 | //! Reads from memory - must return within 500 microseconds 38 | //! @param[in] offset Offset into memory in bytes 39 | //! @param[in,out] size Number of bytes to read, set with the number of bytes read 40 | //! @returns a pointer containing the number of bytes returned in size 41 | virtual const uint8_t* read(uint32_t offset, uint32_t& size) = 0; 42 | 43 | //! Writes to memory - must return within 500 microseconds 44 | //! @param[in] offset Offset into memory in bytes 45 | //! @param[in] data The data to write 46 | //! @param[in,out] size Number of bytes to write, set with number of bytes written 47 | //! @returns true iff all bytes were written or at least queued for write 48 | virtual bool write(uint32_t offset, const void* data, uint32_t& size) = 0; 49 | 50 | //! Used to determine read/write status for status LED 51 | //! @returns the time of last read/write activity 52 | virtual uint64_t getLastActivityTime() = 0; 53 | }; 54 | -------------------------------------------------------------------------------- /inc/hal/Usb/CommandParser.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include "hal/System/MutexInterface.hpp" 31 | 32 | // Command structure: [whitespace][command]<\n> 33 | 34 | //! Command parser for processing commands from a TTY stream 35 | class CommandParser 36 | { 37 | public: 38 | virtual ~CommandParser() {} 39 | 40 | //! @returns the string of command characters this parser handles 41 | virtual const char* getCommandChars() = 0; 42 | 43 | //! Called when newline reached; submit command and reset 44 | virtual void submit(const char* chars, uint32_t len) = 0; 45 | 46 | //! Prints help message for this command 47 | virtual void printHelp() = 0; 48 | 49 | //! When this character is seen, then binary data will proceed 50 | //! For binary commands, 2-byte size followed by payload then final \n character 51 | static const char BINARY_START_CHAR = 0x05; 52 | }; 53 | 54 | void usb_cdc_write(const char *buf, int length); 55 | void usb_cdc_set_echo(bool on); 56 | -------------------------------------------------------------------------------- /inc/hal/Usb/DreamcastControllerObserver.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __DREAMCAST_CONTROLLER_OBSERVER_H__ 25 | #define __DREAMCAST_CONTROLLER_OBSERVER_H__ 26 | 27 | #include 28 | #include "dreamcast_structures.h" 29 | 30 | //! This interface is used to decouple the USB functionality in HAL from the Dreamcast functionality 31 | class DreamcastControllerObserver 32 | { 33 | public: 34 | typedef controller_condition_t ControllerCondition; 35 | typedef vmu_timer_condition_t SecondaryControllerCondition; 36 | 37 | //! Sets the current Dreamcast controller condition 38 | //! @param[in] controllerCondition The current condition of the Dreamcast controller 39 | virtual void setControllerCondition(const ControllerCondition& controllerCondition) = 0; 40 | 41 | //! Sets the current Dreamcast secondary controller condition 42 | //! @param[in] secondaryControllerCondition The current secondary condition of the 43 | //! Dreamcast controller 44 | virtual void setSecondaryControllerCondition( 45 | const SecondaryControllerCondition& secondaryControllerCondition) = 0; 46 | 47 | //! Sets the change condition signal 48 | //! @param[in] changeSignal Send true then false about 25 ms later on change 49 | virtual void setChangeCondition(bool changeSignal) = 0; 50 | 51 | //! Called when controller connected 52 | virtual void controllerConnected() = 0; 53 | 54 | //! Called when controller disconnected 55 | virtual void controllerDisconnected() = 0; 56 | }; 57 | 58 | #endif // __DREAMCAST_CONTROLLER_OBSERVER_H__ 59 | -------------------------------------------------------------------------------- /inc/hal/Usb/TtyParser.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | #include "hal/Usb/CommandParser.hpp" 28 | #include "hal/System/MutexInterface.hpp" 29 | 30 | //! Command parser for processing commands from a TTY stream 31 | class TtyParser 32 | { 33 | public: 34 | //! Virtual destructor 35 | virtual ~TtyParser() {} 36 | //! Adds a command parser to my list of parsers - must be done before any other function called 37 | virtual void addCommandParser(std::shared_ptr parser) = 0; 38 | //! Called from the process receiving characters on the TTY 39 | virtual void addChars(const char* chars, uint32_t len) = 0; 40 | //! Called from the process handling maple bus execution 41 | virtual void process() = 0; 42 | //! When this character is seen, then binary data will proceed 43 | //! For binary commands, 2-byte size followed by payload then final \n character 44 | static const char BINARY_START_CHAR = CommandParser::BINARY_START_CHAR; 45 | }; 46 | 47 | void usb_cdc_set_parser(TtyParser* parser); 48 | -------------------------------------------------------------------------------- /inc/hal/Usb/UsbFile.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __USB_FILE_H__ 25 | #define __USB_FILE_H__ 26 | 27 | #include 28 | 29 | //! Interface for a dreamcast device to inherit when it must show as a file on mass storage 30 | class UsbFile 31 | { 32 | public: 33 | //! Virtual destructor 34 | virtual ~UsbFile() {} 35 | //! @returns file name 36 | virtual const char* getFileName() = 0; 37 | //! @returns file size in bytes (currently only up to 128KB supported) 38 | virtual uint32_t getFileSize() = 0; 39 | //! @returns true iff this file is read only 40 | virtual bool isReadOnly() = 0; 41 | //! Blocking read (must only be called from the core not operating maple bus) 42 | //! @param[in] blockNum Block number to read (a block is 512 bytes) 43 | //! @param[out] buffer Buffer output 44 | //! @param[in] bufferLen The length of buffer (only up to 512 bytes will be read) 45 | //! @param[in] timeoutUs Timeout in microseconds 46 | //! @returns Positive value indicating how many bytes were read 47 | //! @returns Zero if read failure occurred 48 | //! @returns Negative value if timeout elapsed 49 | virtual int32_t read(uint8_t blockNum, 50 | void* buffer, 51 | uint16_t bufferLen, 52 | uint32_t timeoutUs) = 0; 53 | //! Blocking write (must only be called from the core not operating maple bus) 54 | //! @param[in] blockNum Block number to write (block is 512 bytes) 55 | //! @param[in] buffer Buffer 56 | //! @param[in] bufferLen The length of buffer (but only up to 512 bytes will be written) 57 | //! @param[in] timeoutUs Timeout in microseconds 58 | //! @returns Positive value indicating how many bytes were written 59 | //! @returns Zero if write failure occurred 60 | //! @returns Negative value if timeout elapsed 61 | virtual int32_t write(uint8_t blockNum, 62 | const void* buffer, 63 | uint16_t bufferLen, 64 | uint32_t timeoutUs) = 0; 65 | }; 66 | 67 | #endif // __USB_FILE_H__ 68 | -------------------------------------------------------------------------------- /inc/hal/Usb/UsbFileSystem.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __USB_FILE_SYSTEM_H__ 25 | #define __USB_FILE_SYSTEM_H__ 26 | 27 | #include 28 | 29 | class UsbFile; 30 | 31 | //! Interface for USB MSC to receive files 32 | class UsbFileSystem 33 | { 34 | public: 35 | //! Virtual destructor 36 | virtual ~UsbFileSystem() {} 37 | //! Add a file to the mass storage device 38 | virtual void add(UsbFile* file) = 0; 39 | //! Remove a file from the mass storage device 40 | virtual void remove(UsbFile* file) = 0; 41 | }; 42 | 43 | #endif // __USB_FILE_SYSTEM_H__ 44 | -------------------------------------------------------------------------------- /inc/hal/Usb/client_usb_interface.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include 25 | 26 | extern "C" { 27 | void set_usb_descriptor_number_of_gamepads(uint8_t num); 28 | uint8_t get_usb_descriptor_number_of_gamepads(); 29 | } -------------------------------------------------------------------------------- /inc/hal/Usb/host_usb_interface.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "VibrationObserver.hpp" 27 | 28 | //! USB initialization 29 | void usb_init(); 30 | //! USB task that needs to be called constantly by main() 31 | void usb_task(uint64_t timeUs); 32 | //! @returns pointer to the vibration observer for the USB host 33 | VibrationObserver* get_usb_vibration_observer(); -------------------------------------------------------------------------------- /inc/hal/Usb/usb_interface.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __USB_INTERFACE_H__ 25 | #define __USB_INTERFACE_H__ 26 | 27 | #include "UsbFileSystem.hpp" 28 | #include "DreamcastControllerObserver.hpp" 29 | #include "hal/System/MutexInterface.hpp" 30 | #include 31 | 32 | //! @returns array of the USB controller observers 33 | DreamcastControllerObserver** get_usb_controller_observers(); 34 | //! USB initialization 35 | void usb_init( 36 | MutexInterface* mscMutex, 37 | MutexInterface* cdcStdioMutex); 38 | //! USB task that needs to be called constantly by main() 39 | void usb_task(); 40 | //! @returns number of USB controllers 41 | uint32_t get_num_usb_controllers(); 42 | 43 | //! Must return the file system 44 | UsbFileSystem& usb_msc_get_file_system(); 45 | 46 | 47 | #endif // __USB_INTERFACE_H__ 48 | -------------------------------------------------------------------------------- /inc/utils.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __UTILS_H__ 25 | #define __UTILS_H__ 26 | 27 | #include 28 | 29 | #include "configuration.h" 30 | 31 | #define INT_DIVIDE_CEILING(x,y) (((x) + (y) - 1) / (y)) 32 | #define INT_DIVIDE_ROUND(x,y) (((x) + ((y) / 2)) / (y)) 33 | // Just for completeness... 34 | #define INT_DIVIDE_FLOOR(x,y) ((x)/(y)) 35 | 36 | #if SHOW_DEBUG_MESSAGES && !defined(UNITTEST) 37 | #include 38 | #define DEBUG_PRINT(...) printf (__VA_ARGS__) 39 | #else 40 | #define DEBUG_PRINT(...) 41 | #endif 42 | 43 | template 44 | inline T limit_value(T value, T min, T max) 45 | { 46 | return std::min(std::max(value, min), max); 47 | } 48 | 49 | #endif // __UTILS_H__ 50 | -------------------------------------------------------------------------------- /measurements/Dreamcast-Power-Up-Digital-and-Analog-Player1-Controller-VMU-JumpPack.sal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/measurements/Dreamcast-Power-Up-Digital-and-Analog-Player1-Controller-VMU-JumpPack.sal -------------------------------------------------------------------------------- /measurements/README.md: -------------------------------------------------------------------------------- 1 | This directory contains measurements taken with Saleae software. Download the software at https://www.saleae.com/downloads/ in order to view contents of .sal files. -------------------------------------------------------------------------------- /measurements/maple bus test 1.sal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/measurements/maple bus test 1.sal -------------------------------------------------------------------------------- /measurements/maple bus test 2.sal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/measurements/maple bus test 2.sal -------------------------------------------------------------------------------- /measurements/maple bus test 3.sal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/measurements/maple bus test 3.sal -------------------------------------------------------------------------------- /measurements/maple bus test 4.sal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/measurements/maple bus test 4.sal -------------------------------------------------------------------------------- /measurements/maple bus test 5.sal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/measurements/maple bus test 5.sal -------------------------------------------------------------------------------- /measurements/maple bus test 6.sal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/measurements/maple bus test 6.sal -------------------------------------------------------------------------------- /pcb/CAMOutputs/Assembly/PnP_DreamPicoPortSchem_back.txt: -------------------------------------------------------------------------------- 1 | CA 14.14 59.82 270.00 0.1uf CAPC1608X85 2 | CB 14.14 38.04 270.00 0.1uf CAPC1608X85 3 | CC 20.86 59.94 270.00 0.1uf CAPC1608X85 4 | CD 20.86 38.04 270.00 0.1uf CAPC1608X85 5 | J1 15.17 5.04 0.00 FFC3B07-20-T GCT_FFC3B07-20-T 6 | R29 10.71 58.42 0.00 NP RESC1005X40 7 | R30 10.71 61.21 0.00 NP RESC1005X40 8 | R31 10.71 36.58 0.00 NP RESC1005X40 9 | R32 10.71 39.43 0.00 NP RESC1005X40 10 | R33 17.51 58.55 180.00 NP RESC1005X40 11 | R34 17.51 61.28 180.00 NP RESC1005X40 12 | R35 17.51 36.70 180.00 NP RESC1005X40 13 | R36 17.51 39.50 180.00 NP RESC1005X40 14 | RA1 6.77 21.72 90.00 68 RESC1608X60 15 | RA2 9.12 21.72 90.00 68 RESC1608X60 16 | RA3 12.01 54.36 180.00 560 RESC1608X60 17 | RA4 12.01 52.71 180.00 560 RESC1608X60 18 | RA5 9.12 65.41 90.00 10k RESC1608X60 19 | RA6 11.47 65.41 90.00 100k RESC1608X60 20 | RA7 13.82 65.41 90.00 100k RESC1608X60 21 | RB1 11.47 21.72 90.00 68 RESC1608X60 22 | RB2 13.82 21.72 90.00 68 RESC1608X60 23 | RB3 12.01 32.38 180.00 560 RESC1608X60 24 | RB4 12.01 30.73 180.00 560 RESC1608X60 25 | RB5 9.12 44.01 270.00 10k RESC1608X60 26 | RB6 11.47 44.01 90.00 100k RESC1608X60 27 | RB7 13.82 44.01 90.00 100k RESC1608X60 28 | RC1 16.18 21.72 270.00 68 RESC1608X60 29 | RC2 18.53 21.72 270.00 68 RESC1608X60 30 | RC3 17.61 54.36 0.00 560 RESC1608X60 31 | RC4 17.61 52.71 0.00 560 RESC1608X60 32 | RC5 16.18 65.41 270.00 10k RESC1608X60 33 | RC6 18.53 65.41 90.00 100k RESC1608X60 34 | RC7 20.88 65.41 90.00 100k RESC1608X60 35 | RD1 20.88 21.72 270.00 68 RESC1608X60 36 | RD2 23.23 21.72 270.00 68 RESC1608X60 37 | RD3 17.61 32.38 0.00 560 RESC1608X60 38 | RD4 17.61 30.73 0.00 560 RESC1608X60 39 | RD5 16.18 44.01 90.00 10k RESC1608X60 40 | RD6 18.53 44.01 90.00 100k RESC1608X60 41 | RD7 20.88 44.01 90.00 100k RESC1608X60 42 | UA 10.67 59.82 0.00 74LVC2T45DC,125VSSOP8_74LVC2T45DC,125_NEX VSSOP8_74LVC2T45DC,125_NEX 43 | UB 10.67 38.04 0.00 74LVC2T45DC,125VSSOP8_74LVC2T45DC,125_NEX VSSOP8_74LVC2T45DC,125_NEX 44 | UC 17.53 59.88 0.00 74LVC2T45DC,125VSSOP8_74LVC2T45DC,125_NEX VSSOP8_74LVC2T45DC,125_NEX 45 | UD 17.53 38.10 0.00 74LVC2T45DC,125VSSOP8_74LVC2T45DC,125_NEX VSSOP8_74LVC2T45DC,125_NEX 46 | -------------------------------------------------------------------------------- /pcb/CAMOutputs/Assembly/PnP_DreamPicoPortSchem_front.txt: -------------------------------------------------------------------------------- 1 | 3.3V 16.00 17.21 0.00 PINHD-1X1 1X01 2 | 5V 13.46 17.21 0.00 PINHD-1X1 1X01 3 | BAT 23.62 17.14 0.00 PINHD-1X1 1X01 4 | C5 6.86 17.38 90.00 35ZLH100MEFC6.3X11CAP_YX_6P3X11_RUB CAP_YX_6P3X11_RUB 5 | FAN 26.16 17.14 0.00 PINHD-1X1 1X01 6 | GND 18.54 17.21 0.00 PINHD-1X1 1X01 7 | JP1 3.18 10.54 0.00 PINHD-2X2 2X02 8 | JP2 11.05 10.54 0.00 PINHD-2X2 2X02 9 | JP3 18.92 10.54 0.00 PINHD-2X2 2X02 10 | JP4 26.80 10.54 0.00 PINHD-2X2 2X02 11 | LED 21.08 17.14 0.00 PINHD-1X1 1X01 12 | U1 14.99 49.00 0.00 PICO-PKG-NO_DEBUG 13 | -------------------------------------------------------------------------------- /pcb/CAMOutputs/DrillFiles/drill_1_16.xln: -------------------------------------------------------------------------------- 1 | M48 2 | ;GenerationSoftware,Autodesk,EAGLE,9.7.0*% 3 | ;CreationDate,2025-04-19T15:23:02Z*% 4 | FMAT,2 5 | ICI,OFF 6 | METRIC,TZ,000.000 7 | T5C0.350 8 | T4C0.762 9 | T3C1.000 10 | T2C1.016 11 | T1C2.400 12 | % 13 | G90 14 | M71 15 | T1 16 | X20686Y72611 17 | X9286Y72611 18 | X20687Y25497 19 | X9286Y25497 20 | X27784Y21717 21 | X2384Y21717 22 | T2 23 | X13462Y17209 24 | X18542Y17209 25 | X28067Y11811 26 | X28067Y9271 27 | X25527Y9271 28 | X20193Y11811 29 | X20193Y9271 30 | X17653Y11811 31 | X17653Y9271 32 | X12319Y11811 33 | X12319Y9271 34 | X9779Y11811 35 | X9779Y9271 36 | X4445Y11811 37 | X25527Y11811 38 | X4445Y9271 39 | X16002Y17209 40 | X1905Y11811 41 | X1905Y9271 42 | X26162Y17145 43 | X23622Y17145 44 | X21082Y17145 45 | T3 46 | X6096Y47734 47 | X6096Y45194 48 | X6096Y42654 49 | X6096Y40114 50 | X6096Y37574 51 | X6096Y35034 52 | X6096Y32494 53 | X6096Y29954 54 | X6096Y27414 55 | X6096Y24874 56 | X23876Y24874 57 | X23876Y27414 58 | X23876Y29954 59 | X23876Y32494 60 | X23876Y35034 61 | X23876Y40114 62 | X23876Y42654 63 | X23876Y45194 64 | X23876Y47734 65 | X23876Y50274 66 | X23876Y52814 67 | X23876Y55354 68 | X23876Y57894 69 | X23876Y60434 70 | X23876Y62974 71 | X23876Y65514 72 | X23876Y68054 73 | X23876Y70594 74 | X23876Y73134 75 | X23876Y37574 76 | X6096Y73134 77 | X6096Y70594 78 | X6096Y57894 79 | X6096Y55354 80 | X6096Y68054 81 | X6096Y65514 82 | X6096Y60434 83 | X6096Y62974 84 | X6096Y52814 85 | X6096Y50274 86 | T4 87 | X6858Y16129 88 | X6858Y18629 89 | T5 90 | X19050Y36576 91 | X20269Y36119 92 | X11125Y59284 93 | X11278Y55474 94 | X13411Y39929 95 | X12751Y41148 96 | X21946Y60808 97 | X15291Y63246 98 | X10058Y59588 99 | X12802Y45568 100 | X10516Y37490 101 | X10516Y38405 102 | X18898Y61417 103 | X16916Y51664 104 | X22250Y46330 105 | X16154Y61417 106 | X15850Y58369 107 | X19812Y22403 108 | X23927Y23470 109 | X27280Y56083 110 | X22697Y63612 111 | X17069Y57607 112 | X17678Y63703 113 | X17374Y33528 114 | X19050Y35509 115 | X16154Y36576 116 | X17526Y21793 117 | X23470Y11125 118 | X7468Y4877 119 | X17831Y51664 120 | X26365Y10820 121 | X16764Y7772 122 | X15545Y33071 123 | X8077Y66294 124 | X19660Y53950 125 | X17678Y45720 126 | X16916Y38252 127 | X19202Y58369 128 | X16916Y46330 129 | X17069Y59893 130 | X16154Y34290 131 | X18136Y37643 132 | X21336Y10516 133 | X5029Y7620 134 | M30 -------------------------------------------------------------------------------- /pcb/CAMOutputs/GerberFiles/gerber_job.gbrjob: -------------------------------------------------------------------------------- 1 | { 2 | "Header": { 3 | "Comment": "All values are metric (mm)", 4 | "CreationDate": "2025-04-19T15:23:02Z", 5 | "GenerationSoftware": { 6 | "Application": "Fusion Electronics", 7 | "Vendor": "Autodesk", 8 | "Version": "9.7.0" 9 | }, 10 | "Part": "Single" 11 | }, 12 | "Overall": { 13 | "BoardThickness": 1.57, 14 | "LayerNumber": 2, 15 | "Name": { 16 | "ProjectId": "DreamPicoPortSchem v65" 17 | }, 18 | "Owner": "jmsmith86 jmsmith86 ", 19 | "Size": { 20 | "X": 30, 21 | "Y": 75 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /pcb/CAMOutputs/GerberFiles/profile.gbr: -------------------------------------------------------------------------------- 1 | G04 EAGLE Gerber RS-274X export* 2 | G75* 3 | %MOMM*% 4 | %FSLAX34Y34*% 5 | %LPD*% 6 | %IN*% 7 | %IPPOS*% 8 | %AMOC8* 9 | 5,1,8,0,0,1.08239X$1,22.5*% 10 | G01* 11 | G04 Define Apertures* 12 | %ADD10C,0.254000*% 13 | D10* 14 | X0Y0D02* 15 | X300000Y0D01* 16 | X300000Y750000D01* 17 | X0Y750000D01* 18 | X0Y0D01* 19 | M02* 20 | -------------------------------------------------------------------------------- /pcb/CAMOutputs/GerberFiles/solderpaste_top.gbr: -------------------------------------------------------------------------------- 1 | G04 EAGLE Gerber RS-274X export* 2 | G75* 3 | %MOMM*% 4 | %FSLAX34Y34*% 5 | %LPD*% 6 | %INSolderpaste Top*% 7 | %IPPOS*% 8 | %AMOC8* 9 | 5,1,8,0,0,1.08239X$1,22.5*% 10 | G01* 11 | G04 Define Apertures* 12 | %ADD10R,3.500000X1.700000*% 13 | D10* 14 | X49860Y731340D03* 15 | X49860Y705940D03* 16 | X49860Y680540D03* 17 | X49860Y655140D03* 18 | X49860Y629740D03* 19 | X49860Y604340D03* 20 | X49860Y578940D03* 21 | X49860Y553540D03* 22 | X49860Y528140D03* 23 | X49860Y502740D03* 24 | X49860Y477340D03* 25 | X49860Y451940D03* 26 | X49860Y426540D03* 27 | X49860Y401140D03* 28 | X49860Y375740D03* 29 | X49860Y350340D03* 30 | X49860Y324940D03* 31 | X49860Y299540D03* 32 | X49860Y274140D03* 33 | X49860Y248740D03* 34 | X249860Y248740D03* 35 | X249860Y274140D03* 36 | X249860Y299540D03* 37 | X249860Y324940D03* 38 | X249860Y350340D03* 39 | X249860Y375740D03* 40 | X249860Y401140D03* 41 | X249860Y426540D03* 42 | X249860Y451940D03* 43 | X249860Y477340D03* 44 | X249860Y502740D03* 45 | X249860Y528140D03* 46 | X249860Y553540D03* 47 | X249860Y578940D03* 48 | X249860Y604340D03* 49 | X249860Y629740D03* 50 | X249860Y655140D03* 51 | X249860Y680540D03* 52 | X249860Y705940D03* 53 | X249860Y731340D03* 54 | M02* 55 | -------------------------------------------------------------------------------- /pcb/DreamPicoPortSchem.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/pcb/DreamPicoPortSchem.3mf -------------------------------------------------------------------------------- /pcb/acknowledgements.txt: -------------------------------------------------------------------------------- 1 | The following projects/sites were used for part libraries 2 | https://github.com/Lobo-T/RPI-Pico-Eagle-lib 3 | https://github.com/sparkfun/SparkFun-Eagle-Libraries 4 | https://www.digikey.com/ -------------------------------------------------------------------------------- /pcb/board-bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/pcb/board-bottom.png -------------------------------------------------------------------------------- /pcb/board-examples.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/pcb/board-examples.jpg -------------------------------------------------------------------------------- /pcb/board-top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/pcb/board-top.png -------------------------------------------------------------------------------- /run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . ./build_tests.sh 4 | 5 | STATUS=$? 6 | if [ $STATUS -ne 0 ]; then 7 | echo "CMake returned error exit code: ${STATUS}" 8 | echo "Exiting" 9 | exit $STATUS 10 | fi 11 | 12 | cmake \ 13 | --build ${BUILD_DIR} \ 14 | --config Debug \ 15 | --target test \ 16 | -j 10 \ 17 | 18 | STATUS=$? 19 | if [ $STATUS -ne 0 ]; then 20 | echo "CMake returned error exit code: ${STATUS}" 21 | echo "Exiting" 22 | exit $STATUS 23 | fi 24 | -------------------------------------------------------------------------------- /scripts/a.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/scripts/a.bmp -------------------------------------------------------------------------------- /scripts/b.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/scripts/b.bmp -------------------------------------------------------------------------------- /scripts/c.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/scripts/c.bmp -------------------------------------------------------------------------------- /scripts/d.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/scripts/d.bmp -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | if(ENABLE_UNIT_TEST) 6 | add_subdirectory(test) 7 | else() 8 | add_subdirectory(hal) 9 | add_subdirectory(main) 10 | endif() 11 | 12 | add_subdirectory(hostLib) 13 | add_subdirectory(clientLib) -------------------------------------------------------------------------------- /src/clientLib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | file(GLOB SRC "${CMAKE_CURRENT_SOURCE_DIR}/*.c*") 6 | 7 | add_library(clientLib STATIC ${SRC}) 8 | 9 | target_link_libraries(clientLib 10 | PRIVATE 11 | # TODO: move this to HAL 12 | hardware_flash 13 | ) 14 | 15 | if(NOT ENABLE_UNIT_TEST) 16 | target_compile_options(clientLib PRIVATE 17 | -Wall 18 | -Werror 19 | -O3 20 | ) 21 | endif() 22 | 23 | target_include_directories(clientLib 24 | PUBLIC 25 | "$" 26 | "$" 27 | "${PROJECT_SOURCE_DIR}/inc" 28 | "${CMAKE_CURRENT_SOURCE_DIR}/peripherals" 29 | "${CMAKE_CURRENT_SOURCE_DIR}/parsers") 30 | -------------------------------------------------------------------------------- /src/clientLib/DreamcastPeripheralFunction.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "hal/MapleBus/MaplePacket.hpp" 32 | 33 | namespace client 34 | { 35 | 36 | class DreamcastPeripheralFunction 37 | { 38 | public: 39 | //! Constructor 40 | //! @param[in] functionCode The function code (mask) for this peripheral function 41 | inline DreamcastPeripheralFunction(uint32_t functionCode) : 42 | mFunctionCode(functionCode) 43 | { 44 | // One and only one bit may be set for the function code 45 | std::bitset<32> leftBits(mFunctionCode); 46 | assert(leftBits.count() == 1); 47 | } 48 | 49 | //! Virtual destructor 50 | virtual inline ~DreamcastPeripheralFunction() {} 51 | 52 | //! Handle packet meant for this peripheral function 53 | //! @param[in] in The packet read from the Maple Bus 54 | //! @param[out] out The packet to write to the Maple Bus when true is returned 55 | //! @returns true iff the packet was handled 56 | virtual bool handlePacket(const MaplePacket& in, MaplePacket& out) = 0; 57 | 58 | //! Called when player index changed or timeout occurred 59 | virtual void reset() = 0; 60 | 61 | //! @returns function code (mask) for this peripheral function 62 | uint32_t getFunctionCode() { return mFunctionCode; } 63 | 64 | //! @returns the function definition for this peripheral function 65 | virtual uint32_t getFunctionDefinition() = 0; 66 | 67 | private: 68 | DreamcastPeripheralFunction() = delete; 69 | 70 | protected: 71 | //! The function code (mask) for this peripheral function 72 | const uint32_t mFunctionCode; 73 | }; 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/clientLib/DreamcastScreen.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "DreamcastPeripheralFunction.hpp" 27 | #include "dreamcast_constants.h" 28 | 29 | #include 30 | 31 | namespace client 32 | { 33 | class DreamcastScreen : public DreamcastPeripheralFunction 34 | { 35 | public: 36 | typedef void (*ScreenFn)(const uint32_t* screen, uint32_t len); 37 | 38 | public: 39 | DreamcastScreen(ScreenFn callback, uint8_t width = 48, uint8_t height = 32); 40 | 41 | //! Handle packet meant for this peripheral function 42 | //! @param[in] in The packet read from the Maple Bus 43 | //! @param[out] out The packet to write to the Maple Bus when true is returned 44 | //! @returns true iff the packet was handled 45 | virtual bool handlePacket(const MaplePacket& in, MaplePacket& out) final; 46 | 47 | //! Called when player index changed or timeout occurred 48 | virtual void reset() final; 49 | 50 | //! @returns the function definition for this peripheral function 51 | virtual uint32_t getFunctionDefinition() final; 52 | 53 | private: 54 | //! This screen's pixel width 55 | const uint8_t mWidth; 56 | //! This screen's pixel height 57 | const uint8_t mHeight; 58 | //! Callback function which sets screen data 59 | ScreenFn mCallback; 60 | 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /src/clientLib/README.md: -------------------------------------------------------------------------------- 1 | # clientLib 2 | 3 | This directory contains code to control the Maple Bus as a client. This library is not meant to be compatible in conjunction with hostLib. -------------------------------------------------------------------------------- /src/hal/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | add_subdirectory(MapleBus) 6 | add_subdirectory(System) 7 | add_subdirectory(Usb) 8 | -------------------------------------------------------------------------------- /src/hal/MapleBus/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | file(GLOB SRC "${CMAKE_CURRENT_SOURCE_DIR}/*.c*") 6 | 7 | add_library(hal-MapleBus STATIC ${SRC}) 8 | pico_generate_pio_header(hal-MapleBus ${CMAKE_CURRENT_LIST_DIR}/maple_in.pio) 9 | pico_generate_pio_header(hal-MapleBus ${CMAKE_CURRENT_LIST_DIR}/maple_out.pio) 10 | target_link_libraries(hal-MapleBus 11 | PUBLIC 12 | pico_stdlib 13 | pico_unique_id 14 | hardware_pio 15 | hardware_dma 16 | ) 17 | target_compile_options(hal-MapleBus PRIVATE 18 | -Wall 19 | -Werror 20 | -O3 21 | ) 22 | 23 | target_include_directories(hal-MapleBus 24 | PUBLIC 25 | "$" 26 | "$" 27 | "${PROJECT_SOURCE_DIR}/inc") 28 | -------------------------------------------------------------------------------- /src/hal/MapleBus/PioProgram.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "hardware/pio.h" 27 | 28 | class PioProgram 29 | { 30 | public: 31 | inline PioProgram(pio_hw_t* pio, const pio_program_t *program) : 32 | mPio(pio), 33 | mProgram(program), 34 | mProgramOffset(pio_add_program(pio, program)) 35 | {} 36 | 37 | pio_hw_t* const mPio; 38 | const pio_program_t* const mProgram; 39 | const uint mProgramOffset; 40 | }; 41 | -------------------------------------------------------------------------------- /src/hal/System/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | file(GLOB SRC "${CMAKE_CURRENT_SOURCE_DIR}/*.c*") 6 | 7 | add_library(hal-System STATIC ${SRC}) 8 | target_link_libraries(hal-System 9 | PUBLIC 10 | pico_stdlib 11 | hardware_flash 12 | hardware_pwm 13 | pico_unique_id 14 | ) 15 | target_compile_options(hal-System PRIVATE 16 | -Wall 17 | -Werror 18 | -O3 19 | ) 20 | 21 | target_include_directories(hal-System 22 | PUBLIC 23 | "$" 24 | "$" 25 | "${PROJECT_SOURCE_DIR}/inc") 26 | -------------------------------------------------------------------------------- /src/hal/System/Clock.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "Clock.hpp" 25 | 26 | #include "pico/stdlib.h" 27 | 28 | uint64_t Clock::getTimeUs() const 29 | { 30 | return time_us_64(); 31 | } 32 | -------------------------------------------------------------------------------- /src/hal/System/Clock.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __CLOCK_H__ 25 | #define __CLOCK_H__ 26 | 27 | #include "hal/System/ClockInterface.hpp" 28 | 29 | class Clock : public ClockInterface 30 | { 31 | public: 32 | virtual uint64_t getTimeUs() const final; 33 | }; 34 | 35 | #endif // __CLOCK_H__ 36 | -------------------------------------------------------------------------------- /src/hal/System/CriticalSectionMutex.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "CriticalSectionMutex.hpp" 25 | 26 | CriticalSectionMutex::CriticalSectionMutex() 27 | { 28 | critical_section_init(&mCriticalSection); 29 | } 30 | 31 | CriticalSectionMutex::~CriticalSectionMutex() {} 32 | 33 | void CriticalSectionMutex::lock() 34 | { 35 | critical_section_enter_blocking(&mCriticalSection); 36 | } 37 | 38 | void CriticalSectionMutex::unlock() 39 | { 40 | critical_section_exit(&mCriticalSection); 41 | } 42 | 43 | int8_t CriticalSectionMutex::tryLock() 44 | { 45 | // "try" isn't valid for critical section mutex, but taking will never cause deadlock since 46 | // interrupts are disabled as part of the locking mechanism. 47 | return 0; 48 | } -------------------------------------------------------------------------------- /src/hal/System/CriticalSectionMutex.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __CRITICAL_SECTION_MUTEX_H__ 25 | #define __CRITICAL_SECTION_MUTEX_H__ 26 | 27 | #include "hal/System/MutexInterface.hpp" 28 | #include "pico/critical_section.h" 29 | 30 | // From raspberry-pi-pico-c-sdk.pdf: 31 | // Critical Section API for short-lived mutual exclusion safe for IRQ and multi-core. 32 | // A critical section is non-reentrant, and provides mutual exclusion using a spin-lock to prevent 33 | // access from the other core, and from (higher priority) interrupts on the same core. It does the 34 | // former using a spin lock and the latter by disabling interrupts on the calling core. Because 35 | // interrupts are disabled when a critical_section is owned, uses of the critical_section should be 36 | // as short as possible. 37 | class CriticalSectionMutex : public MutexInterface 38 | { 39 | public: 40 | CriticalSectionMutex(); 41 | 42 | virtual ~CriticalSectionMutex(); 43 | 44 | virtual void lock() final; 45 | 46 | virtual void unlock() final; 47 | 48 | virtual int8_t tryLock() final; 49 | 50 | private: 51 | critical_section_t mCriticalSection; 52 | }; 53 | 54 | #endif // __CRITICAL_SECTION_MUTEX_H__ 55 | -------------------------------------------------------------------------------- /src/hal/System/Mutex.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "Mutex.hpp" 25 | 26 | Mutex::Mutex() 27 | { 28 | mutex_init(&mMutex); 29 | } 30 | 31 | Mutex::~Mutex() {} 32 | 33 | void Mutex::lock() 34 | { 35 | mutex_enter_blocking(&mMutex); 36 | } 37 | 38 | void Mutex::unlock() 39 | { 40 | mutex_exit(&mMutex); 41 | } 42 | 43 | int8_t Mutex::tryLock() 44 | { 45 | uint32_t owner; 46 | if (!mutex_try_enter(&mMutex, &owner)) 47 | { 48 | if (owner == get_core_num()) 49 | { 50 | return -1; // would deadlock 51 | } 52 | else 53 | { 54 | return 0; 55 | } 56 | } 57 | return 1; 58 | } 59 | -------------------------------------------------------------------------------- /src/hal/System/Mutex.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __MUTEX_H__ 25 | #define __MUTEX_H__ 26 | 27 | #include "hal/System/MutexInterface.hpp" 28 | #include "pico/mutex.h" 29 | 30 | // From raspberry-pi-pico-c-sdk.pdf: 31 | // Mutex API for non IRQ mutual exclusion between cores. 32 | // Unlike critical sections, the mutex protected code is not necessarily required/expected to 33 | // complete quickly as no other sytem wide locks are held on account of an acquired mutex. 34 | class Mutex : public MutexInterface 35 | { 36 | public: 37 | Mutex(); 38 | 39 | virtual ~Mutex(); 40 | 41 | virtual void lock() final; 42 | 43 | virtual void unlock() final; 44 | 45 | virtual int8_t tryLock() final; 46 | 47 | private: 48 | mutex_t mMutex; 49 | }; 50 | 51 | #endif // __MUTEX_H__ 52 | -------------------------------------------------------------------------------- /src/hal/System/PicoIdentification.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pico/unique_id.h" 3 | 4 | #include 5 | 6 | std::uint32_t PicoIdentification::getSerialSize() 7 | { 8 | return (PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1); 9 | } 10 | 11 | void PicoIdentification::getSerial(char* buffer, std::uint32_t bufflen) 12 | { 13 | pico_get_unique_board_id_string(buffer, bufflen); 14 | } -------------------------------------------------------------------------------- /src/hal/System/PicoIdentification.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "pico/unique_id.h" 4 | 5 | class PicoIdentification : public SystemIdentification 6 | { 7 | public: 8 | PicoIdentification() = default; 9 | virtual ~PicoIdentification() = default; 10 | 11 | std::uint32_t getSerialSize() override; 12 | void getSerial(char* buffer, std::uint32_t bufflen) override; 13 | }; 14 | -------------------------------------------------------------------------------- /src/hal/System/VolatileSystemMemory.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "VolatileSystemMemory.hpp" 25 | #include 26 | 27 | #include "pico/stdlib.h" 28 | 29 | VolatileSystemMemory::VolatileSystemMemory(uint32_t size) : 30 | SystemMemory(), 31 | mSize(size), 32 | mMemory(new uint8_t[mSize]) 33 | { 34 | memset(mMemory.get(), 0xFF, mSize); 35 | } 36 | 37 | uint32_t VolatileSystemMemory::getMemorySize() 38 | { 39 | return mSize; 40 | } 41 | 42 | const uint8_t* VolatileSystemMemory::read(uint32_t offset, uint32_t& size) 43 | { 44 | mLastActivityTime = time_us_64(); 45 | 46 | const uint8_t* mem = nullptr; 47 | if (offset >= mSize) 48 | { 49 | size = 0; 50 | } 51 | else 52 | { 53 | mem = &mMemory[offset]; 54 | uint32_t max = mSize - offset; 55 | size = (max >= size) ? size : max; 56 | } 57 | return mem; 58 | } 59 | 60 | bool VolatileSystemMemory::write(uint32_t offset, const void* data, uint32_t& size) 61 | { 62 | mLastActivityTime = time_us_64(); 63 | 64 | bool success = false; 65 | uint8_t* mem = nullptr; 66 | if (offset >= mSize) 67 | { 68 | size = 0; 69 | } 70 | else 71 | { 72 | mem = &mMemory[offset]; 73 | uint32_t max = mSize - offset; 74 | if (max >= size) 75 | { 76 | success = true; 77 | } 78 | else 79 | { 80 | size = max; 81 | } 82 | memcpy(mem, data, size); 83 | } 84 | return success; 85 | } 86 | 87 | uint64_t VolatileSystemMemory::getLastActivityTime() 88 | { 89 | // WARNING: Not an atomic read, but this isn't a critical thing anyway 90 | return mLastActivityTime; 91 | } 92 | -------------------------------------------------------------------------------- /src/hal/System/VolatileSystemMemory.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "hal/System/SystemMemory.hpp" 27 | 28 | #include 29 | #include 30 | 31 | class VolatileSystemMemory : public SystemMemory 32 | { 33 | public: 34 | //! Constructor 35 | //! @param[in] size Number of bytes to reserve in volatile memory 36 | VolatileSystemMemory(uint32_t size); 37 | 38 | //! @returns number of bytes reserved in memory 39 | virtual uint32_t getMemorySize() final; 40 | 41 | //! Reads from memory - must return within 500 microseconds 42 | //! @param[in] offset Offset into memory in bytes 43 | //! @param[in,out] size Number of bytes to read, set with the number of bytes read 44 | //! @returns a pointer containing the number of bytes returned in size 45 | virtual const uint8_t* read(uint32_t offset, uint32_t& size) final; 46 | 47 | //! Writes to memory - must return within 500 microseconds 48 | //! @param[in] offset Offset into memory in bytes 49 | //! @param[in] data The data to write 50 | //! @param[in,out] size Number of bytes to write, set with number of bytes written 51 | //! @returns true iff all bytes were written or at least queued for write 52 | virtual bool write(uint32_t offset, const void* data, uint32_t& size) final; 53 | 54 | //! Used to determine read/write status for status LED 55 | //! @returns the time of last read/write activity 56 | virtual uint64_t getLastActivityTime() final; 57 | 58 | private: 59 | //! Number of bytes in volatile memory 60 | const uint32_t mSize; 61 | //! The volatile memory 62 | std::shared_ptr mMemory; 63 | //! Last system time of read/write activity 64 | uint64_t mLastActivityTime; 65 | }; 66 | -------------------------------------------------------------------------------- /src/hal/Usb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | add_subdirectory(Client) 6 | add_subdirectory(Host) 7 | -------------------------------------------------------------------------------- /src/hal/Usb/Client/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | file(GLOB SRC "${CMAKE_CURRENT_SOURCE_DIR}/*.c*") 6 | 7 | add_library(hal-Usb-Client STATIC ${SRC}) 8 | target_link_libraries(hal-Usb-Client 9 | PUBLIC 10 | pico_stdlib 11 | pico_unique_id 12 | tinyusb_device 13 | tinyusb_board 14 | tinyusb_device_base 15 | ) 16 | target_compile_options(hal-Usb-Client PRIVATE 17 | -Wall 18 | -Werror 19 | -O3 20 | ) 21 | 22 | target_include_directories(hal-Usb-Client 23 | PUBLIC 24 | "$" 25 | "$/../Common" 26 | "$" 27 | "${PROJECT_SOURCE_DIR}/inc") 28 | -------------------------------------------------------------------------------- /src/hal/Usb/Client/UsbControllerDevice.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "UsbControllerDevice.h" 25 | #include 26 | #include "class/hid/hid_device.h" 27 | 28 | UsbControllerDevice::UsbControllerDevice() : mIsUsbConnected(false), mIsControllerConnected(false) {} 29 | UsbControllerDevice::~UsbControllerDevice() {} 30 | 31 | void UsbControllerDevice::updateUsbConnected(bool connected) 32 | { 33 | mIsUsbConnected = connected; 34 | } 35 | 36 | bool UsbControllerDevice::isUsbConnected() 37 | { 38 | return mIsUsbConnected; 39 | } 40 | 41 | void UsbControllerDevice::updateControllerConnected(bool connected) 42 | { 43 | if (connected != mIsControllerConnected) 44 | { 45 | updateAllReleased(); 46 | } 47 | mIsControllerConnected = connected; 48 | } 49 | 50 | bool UsbControllerDevice::isControllerConnected() 51 | { 52 | return mIsControllerConnected; 53 | } 54 | 55 | bool UsbControllerDevice::sendReport(uint8_t instance, uint8_t report_id) 56 | { 57 | bool sent = false; 58 | if (isUsbConnected()) 59 | { 60 | uint8_t reportSize = getReportSize(); 61 | uint8_t reportBuffer[reportSize]; 62 | getReport(reportBuffer, reportSize); 63 | sent = tud_hid_n_report(instance, report_id, reportBuffer, reportSize); 64 | } 65 | return sent; 66 | } 67 | -------------------------------------------------------------------------------- /src/hal/Usb/Client/UsbGamepadDreamcastControllerObserver.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __USB_CONTROLLER_DREAMCAST_CONTROLLER_OBSERVER_H__ 25 | #define __USB_CONTROLLER_DREAMCAST_CONTROLLER_OBSERVER_H__ 26 | 27 | #include "hal/Usb/DreamcastControllerObserver.hpp" 28 | #include "UsbGamepad.h" 29 | 30 | //! Yes, I know this name is ridiculous, but at least it's descriptive! 31 | //! This connects the Dreamcast controller observer to a USB gamepad device 32 | class UsbGamepadDreamcastControllerObserver : public DreamcastControllerObserver 33 | { 34 | public: 35 | //! Constructor for UsbKeyboardGenesisControllerObserver 36 | //! @param[in] usbController The USB controller to update when keys are pressed or released 37 | UsbGamepadDreamcastControllerObserver(UsbGamepad& usbController); 38 | 39 | //! Sets the current Dreamcast controller condition 40 | //! @param[in] controllerCondition The current condition of the Dreamcast controller 41 | virtual void setControllerCondition(const ControllerCondition& controllerCondition) final; 42 | 43 | //! Sets the current Dreamcast secondary controller condition 44 | //! @param[in] secondaryControllerCondition The current secondary condition of the 45 | //! Dreamcast controller 46 | virtual void setSecondaryControllerCondition( 47 | const SecondaryControllerCondition& secondaryControllerCondition) final; 48 | 49 | virtual void setChangeCondition(bool changeSignal) override final; 50 | 51 | //! Called when controller connected 52 | virtual void controllerConnected() final; 53 | 54 | //! Called when controller disconnected 55 | virtual void controllerDisconnected() final; 56 | 57 | private: 58 | //! The USB controller I update 59 | UsbGamepad& mUsbController; 60 | }; 61 | 62 | #endif // __USB_CONTROLLER_DREAMCAST_CONTROLLER_OBSERVER_H__ 63 | -------------------------------------------------------------------------------- /src/hal/Usb/Client/cdc.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "tusb_config.h" 25 | #include "hal/System/MutexInterface.hpp" 26 | #include "hal/System/LockGuard.hpp" 27 | #include 28 | 29 | // CDC is used to create a debug serial interface 30 | 31 | void cdc_init(MutexInterface* cdcStdioMutex); 32 | void cdc_task(); 33 | -------------------------------------------------------------------------------- /src/hal/Usb/Client/msc_disk.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "hal/System/MutexInterface.hpp" 25 | 26 | void msc_init(MutexInterface* mutex); 27 | -------------------------------------------------------------------------------- /src/hal/Usb/Client/usb_descriptors.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __USB_DESCRITORS_H__ 25 | #define __USB_DESCRITORS_H__ 26 | 27 | #include "configuration.h" 28 | #include 29 | 30 | #define GAMEPAD_MAIN_REPORT_ID 1 31 | #define REPORT_ID_DC_RAW_DATA 2 32 | #define GAMEPAD_REPORT_SIZE 64 33 | 34 | #define ITF_NUM_GAMEPAD(idx) (idx) 35 | 36 | #define MAX_NUMBER_OF_USB_GAMEPADS (4) 37 | 38 | // For mass storage device 39 | #define ITF_NUM_MSC (4) 40 | 41 | #if USB_MSC_ENABLED 42 | #define NUM_ITF_MSC (1) 43 | #else 44 | #define NUM_ITF_MSC (0) 45 | #endif 46 | 47 | // For serial device 48 | #define ITF_NUM_CDC (5) 49 | #define ITF_NUM_CDC_DATA (6) // Implied, not directly used 50 | 51 | #if USB_CDC_ENABLED 52 | #define NUM_ITF_CDC (2) 53 | #else 54 | #define NUM_ITF_CDC (0) 55 | #endif 56 | 57 | #define ITF_COUNT(numGamepads) (numGamepads + NUM_ITF_CDC + NUM_ITF_MSC) 58 | 59 | //! Minumum analog value defined in USB HID descriptors 60 | static const int8_t MIN_ANALOG_VALUE = -127; 61 | //! Maximum analog value defined in USB HID descriptors 62 | static const int8_t MAX_ANALOG_VALUE = 127; 63 | //! Minimum trigger value defined in USB HID descriptors 64 | static const int8_t MIN_TRIGGER_VALUE = MIN_ANALOG_VALUE; 65 | //! Maximum trigger value defined in USB HID descriptors 66 | static const int8_t MAX_TRIGGER_VALUE = MAX_ANALOG_VALUE; 67 | 68 | #endif // __USB_DESCRITORS_H__ 69 | -------------------------------------------------------------------------------- /src/hal/Usb/Host/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | file(GLOB SRC "${CMAKE_CURRENT_SOURCE_DIR}/*.c*") 6 | 7 | add_library(hal-Usb-Host STATIC ${SRC}) 8 | target_link_libraries(hal-Usb-Host 9 | PUBLIC 10 | pico_stdlib 11 | tinyusb_board 12 | tinyusb_host 13 | ) 14 | target_compile_options(hal-Usb-Host PRIVATE 15 | -Wall 16 | #-Werror 17 | -O3 18 | ) 19 | 20 | # This is a workaround for a bug in pico-sdk under usb host 21 | target_compile_definitions(tinyusb_host INTERFACE NDEBUG=1) 22 | 23 | target_include_directories(hal-Usb-Host 24 | PUBLIC 25 | "$" 26 | "$/../Common" 27 | "$" 28 | "${PROJECT_SOURCE_DIR}/inc") 29 | -------------------------------------------------------------------------------- /src/hal/Usb/Host/Dualshock4Handler.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "VibrationObserver.hpp" 27 | #include "HidHandler.hpp" 28 | 29 | class Dualshock4Handler : public VibrationObserver, public HidHandler 30 | { 31 | public: 32 | inline Dualshock4Handler() 33 | {} 34 | 35 | virtual inline void vibrate( 36 | float frequency, 37 | float intensity, 38 | int8_t inclination, 39 | float duration) final 40 | {} 41 | 42 | virtual inline void handleReport(uint8_t const* report, uint16_t len) final 43 | {} 44 | }; 45 | -------------------------------------------------------------------------------- /src/hal/Usb/Host/HidHandler.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | 28 | class HidHandler 29 | { 30 | public: 31 | virtual ~HidHandler() {} 32 | 33 | virtual void handleReport(uint8_t const* report, uint16_t len) = 0; 34 | }; -------------------------------------------------------------------------------- /src/hal/Usb/Host/hid_app.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | 28 | void hid_app_task(uint64_t timeUs); -------------------------------------------------------------------------------- /src/hal/Usb/Host/usb_execution.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "hal/Usb/host_usb_interface.hpp" 25 | 26 | #include "hid_app.hpp" 27 | 28 | #include "tusb_config.h" 29 | #include "bsp/board.h" 30 | #include "tusb.h" 31 | 32 | void usb_init() 33 | { 34 | board_init(); 35 | tusb_init(); 36 | } 37 | 38 | void usb_task(uint64_t timeUs) 39 | { 40 | tuh_task(); 41 | hid_app_task(timeUs); 42 | } 43 | -------------------------------------------------------------------------------- /src/hal/Usb/Host/usb_host.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrangeFox86/DreamPicoPort/6832463e45d503666ebbc353fcef97a236912508/src/hal/Usb/Host/usb_host.cpp -------------------------------------------------------------------------------- /src/hostLib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | file(GLOB SRC "${CMAKE_CURRENT_SOURCE_DIR}/*.c*" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/peripherals/*.c*" 7 | "${CMAKE_CURRENT_SOURCE_DIR}/parsers/*.c*") 8 | 9 | add_library(hostLib STATIC ${SRC}) 10 | 11 | if(NOT ENABLE_UNIT_TEST) 12 | target_compile_options(hostLib PRIVATE 13 | -Wall 14 | -Werror 15 | -O3 16 | ) 17 | endif() 18 | 19 | target_include_directories(hostLib 20 | PUBLIC 21 | "$" 22 | "$" 23 | "${PROJECT_SOURCE_DIR}/inc" 24 | "${CMAKE_CURRENT_SOURCE_DIR}/peripherals" 25 | "${CMAKE_CURRENT_SOURCE_DIR}/parsers") 26 | 27 | if (ENABLE_UNIT_TEST) 28 | add_subdirectory(test) 29 | endif() -------------------------------------------------------------------------------- /src/hostLib/EndpointTxScheduler.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "EndpointTxScheduler.hpp" 25 | 26 | EndpointTxScheduler::EndpointTxScheduler( 27 | std::shared_ptr prioritizedScheduler, 28 | uint8_t fixedPriority, 29 | uint8_t recipientAddr): 30 | mPrioritizedScheduler(prioritizedScheduler), 31 | mFixedPriority(fixedPriority), 32 | mRecipientAddr(recipientAddr) 33 | {} 34 | 35 | EndpointTxScheduler::~EndpointTxScheduler() 36 | {} 37 | 38 | uint32_t EndpointTxScheduler::add(uint64_t txTime, 39 | Transmitter* transmitter, 40 | uint8_t command, 41 | uint32_t* payload, 42 | uint8_t payloadLen, 43 | bool expectResponse, 44 | uint32_t expectedResponseNumPayloadWords, 45 | uint32_t autoRepeatUs, 46 | uint64_t autoRepeatEndTimeUs) 47 | { 48 | MaplePacket packet({.command=command, .recipientAddr=mRecipientAddr}, payload, payloadLen); 49 | return mPrioritizedScheduler->add(mFixedPriority, 50 | txTime, 51 | transmitter, 52 | packet, 53 | expectResponse, 54 | expectedResponseNumPayloadWords, 55 | autoRepeatUs, 56 | autoRepeatEndTimeUs); 57 | } 58 | 59 | uint32_t EndpointTxScheduler::cancelById(uint32_t transmissionId) 60 | { 61 | return mPrioritizedScheduler->cancelById(transmissionId); 62 | } 63 | 64 | uint32_t EndpointTxScheduler::cancelByRecipient(uint8_t recipientAddr) 65 | { 66 | return mPrioritizedScheduler->cancelByRecipient(recipientAddr); 67 | } 68 | 69 | uint32_t EndpointTxScheduler::countRecipients(uint8_t recipientAddr) 70 | { 71 | return mPrioritizedScheduler->countRecipients(recipientAddr); 72 | } 73 | 74 | uint32_t EndpointTxScheduler::cancelAll() 75 | { 76 | return mPrioritizedScheduler->cancelAll(); 77 | } -------------------------------------------------------------------------------- /src/hostLib/PlayerData.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "hal/Usb/DreamcastControllerObserver.hpp" 27 | #include "hal/System/ClockInterface.hpp" 28 | #include "ScreenData.hpp" 29 | #include "hal/Usb/UsbFileSystem.hpp" 30 | 31 | //! Contains data that is tied to a specific player 32 | struct PlayerData 33 | { 34 | const uint32_t playerIndex; 35 | DreamcastControllerObserver& gamepad; 36 | ScreenData& screenData; 37 | ClockInterface& clock; 38 | UsbFileSystem& fileSystem; 39 | 40 | PlayerData(uint32_t playerIndex, 41 | DreamcastControllerObserver& gamepad, 42 | ScreenData& screenData, 43 | ClockInterface& clock, 44 | UsbFileSystem& fileSystem) : 45 | playerIndex(playerIndex), 46 | gamepad(gamepad), 47 | screenData(screenData), 48 | clock(clock), 49 | fileSystem(fileSystem) 50 | {} 51 | }; -------------------------------------------------------------------------------- /src/hostLib/README.md: -------------------------------------------------------------------------------- 1 | # hostLib 2 | 3 | This directory contains code to control the Maple Bus as a host. This library is not meant to be compatible in conjunction with clientLib. -------------------------------------------------------------------------------- /src/hostLib/Transmission.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | #include 28 | #include "hal/MapleBus/MaplePacket.hpp" 29 | #include "Transmitter.hpp" 30 | 31 | //! Transmission definition 32 | struct Transmission 33 | { 34 | //! Unique ID of this transmission 35 | const uint32_t transmissionId; 36 | //! Priority where 0 is highest 37 | const uint8_t priority; 38 | //! Set to true iff a response is expected 39 | const bool expectResponse; 40 | //! The expected transmission duration (from transmit to end of receive) 41 | const uint32_t txDurationUs; 42 | //! If not 0, the period which this transmission should be repeated in microseconds 43 | const uint32_t autoRepeatUs; 44 | //! If not 0, auto repeat will cancel after this time 45 | const uint64_t autoRepeatEndTimeUs; 46 | //! The next time that this packet is to be transmitted 47 | uint64_t nextTxTimeUs; 48 | //! The packet to transmit 49 | std::shared_ptr packet; 50 | //! The object that added this transmission (for callbacks) 51 | Transmitter* const transmitter; 52 | 53 | Transmission(uint32_t transmissionId, 54 | uint8_t priority, 55 | bool expectResponse, 56 | uint32_t txDurationUs, 57 | uint32_t autoRepeatUs, 58 | uint64_t autoRepeatEndTimeUs, 59 | uint64_t nextTxTimeUs, 60 | std::shared_ptr packet, 61 | Transmitter* transmitter): 62 | transmissionId(transmissionId), 63 | priority(priority), 64 | expectResponse(expectResponse), 65 | txDurationUs(txDurationUs), 66 | autoRepeatUs(autoRepeatUs), 67 | autoRepeatEndTimeUs(autoRepeatEndTimeUs), 68 | nextTxTimeUs(nextTxTimeUs), 69 | packet(packet), 70 | transmitter(transmitter) 71 | {} 72 | 73 | //! @returns the estimated completion time of this transmission 74 | uint64_t getNextCompletionTime(uint64_t executionTime) 75 | { 76 | return executionTime + txDurationUs; 77 | } 78 | }; -------------------------------------------------------------------------------- /src/hostLib/TransmissionTimeliner.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "TransmissionTimeliner.hpp" 25 | #include 26 | 27 | TransmissionTimeliner::TransmissionTimeliner(MapleBusInterface& bus, std::shared_ptr schedule): 28 | mBus(bus), mSchedule(schedule), mCurrentTx(nullptr) 29 | {} 30 | 31 | TransmissionTimeliner::ReadStatus TransmissionTimeliner::readTask(uint64_t currentTimeUs) 32 | { 33 | ReadStatus status; 34 | 35 | // Process bus events and get any data received 36 | MapleBusInterface::Status busStatus = mBus.processEvents(currentTimeUs); 37 | status.busPhase = busStatus.phase; 38 | if (status.busPhase == MapleBusInterface::Phase::READ_COMPLETE) 39 | { 40 | status.received = std::make_shared(busStatus.readBuffer, 41 | busStatus.readBufferLen); 42 | status.transmission = mCurrentTx; 43 | mCurrentTx = nullptr; 44 | } 45 | else if (status.busPhase == MapleBusInterface::Phase::WRITE_COMPLETE 46 | || status.busPhase == MapleBusInterface::Phase::READ_FAILED 47 | || status.busPhase == MapleBusInterface::Phase::WRITE_FAILED) 48 | { 49 | status.transmission = mCurrentTx; 50 | mCurrentTx = nullptr; 51 | } 52 | 53 | return status; 54 | } 55 | 56 | std::shared_ptr TransmissionTimeliner::writeTask(uint64_t currentTimeUs) 57 | { 58 | std::shared_ptr txSent = nullptr; 59 | 60 | if (!mBus.isBusy()) 61 | { 62 | PrioritizedTxScheduler::ScheduleItem item = mSchedule->peekNext(currentTimeUs); 63 | txSent = item.getTx(); 64 | if (txSent != nullptr) 65 | { 66 | if (mBus.write(*txSent->packet, txSent->expectResponse)) 67 | { 68 | mCurrentTx = txSent; 69 | mSchedule->popItem(item); 70 | } 71 | else 72 | { 73 | txSent = nullptr; 74 | } 75 | } 76 | } 77 | 78 | return txSent; 79 | } -------------------------------------------------------------------------------- /src/hostLib/TransmissionTimeliner.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "hal/MapleBus/MaplePacket.hpp" 27 | #include "hal/MapleBus/MapleBusInterface.hpp" 28 | #include "PrioritizedTxScheduler.hpp" 29 | 30 | class TransmissionTimeliner 31 | { 32 | public: 33 | //! Status of the task 34 | struct ReadStatus 35 | { 36 | //! The transmission associated with the data below 37 | std::shared_ptr transmission; 38 | //! Set to received packet or nullptr if nothing received 39 | std::shared_ptr received; 40 | //! The phase of the maple bus 41 | MapleBusInterface::Phase busPhase; 42 | 43 | ReadStatus() : 44 | transmission(nullptr), 45 | received(nullptr), 46 | busPhase(MapleBusInterface::Phase::INVALID) 47 | {} 48 | }; 49 | 50 | public: 51 | //! Constructor 52 | //! @param[in] bus The maple bus that scheduled transmissions are written to 53 | //! @param[in] schedule The schedule to pop transmissions from 54 | TransmissionTimeliner(MapleBusInterface& bus, std::shared_ptr schedule); 55 | 56 | //! Read timeliner task - called periodically to process timeliner read events 57 | //! @param[in] currentTimeUs The current time task is run 58 | //! @returns read status information 59 | ReadStatus readTask(uint64_t currentTimeUs); 60 | 61 | //! Write timeliner task - called periodically to process timeliner write events 62 | //! @param[in] currentTimeUs The current time task is run 63 | //! @returns the transmission that started or nullptr if nothing was transmitted 64 | std::shared_ptr writeTask(uint64_t currentTimeUs); 65 | 66 | protected: 67 | //! The maple bus that scheduled transmissions are written to 68 | MapleBusInterface& mBus; 69 | //! The schedule that transmissions are popped from 70 | std::shared_ptr mSchedule; 71 | //! The currently sending transmission 72 | std::shared_ptr mCurrentTx; 73 | }; -------------------------------------------------------------------------------- /src/hostLib/Transmitter.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | #include 28 | 29 | struct Transmission; 30 | struct MaplePacket; 31 | 32 | class Transmitter 33 | { 34 | public: 35 | Transmitter() {} 36 | virtual ~Transmitter() {} 37 | 38 | //! Called when transmission has started to be sent 39 | //! @param[in] tx The transmission that was sent 40 | virtual void txStarted(std::shared_ptr tx) = 0; 41 | 42 | //! Called when transmission failed 43 | //! @param[in] writeFailed Set to true iff TX failed because write failed 44 | //! @param[in] readFailed Set to true iff TX failed because read failed 45 | //! @param[in] tx The transmission that failed 46 | virtual void txFailed(bool writeFailed, 47 | bool readFailed, 48 | std::shared_ptr tx) = 0; 49 | 50 | //! Called when a transmission is complete 51 | //! @param[in] packet The packet received or nullptr if this was write only transmission 52 | //! @param[in] tx The transmission that triggered this data 53 | virtual void txComplete(std::shared_ptr packet, 54 | std::shared_ptr tx) = 0; 55 | }; 56 | -------------------------------------------------------------------------------- /src/hostLib/parsers/MaplePassthroughCommandParser.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "hal/Usb/CommandParser.hpp" 27 | 28 | #include "PrioritizedTxScheduler.hpp" 29 | 30 | #include 31 | 32 | // Command structure: [whitespace][command]<\n> 33 | 34 | //! Command parser for processing commands from a TTY stream 35 | class MaplePassthroughCommandParser : public CommandParser 36 | { 37 | public: 38 | MaplePassthroughCommandParser(std::shared_ptr* schedulers, 39 | const uint8_t* senderAddresses, 40 | uint32_t numSenders); 41 | 42 | //! @returns the string of command characters this parser handles 43 | virtual const char* getCommandChars() final; 44 | 45 | //! Called when newline reached; submit command and reset 46 | virtual void submit(const char* chars, uint32_t len) final; 47 | 48 | //! Prints help message for this command 49 | virtual void printHelp() final; 50 | 51 | private: 52 | std::shared_ptr* const mSchedulers; 53 | const uint8_t* const mSenderAddresses; 54 | const uint32_t mNumSenders; 55 | }; 56 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastArGun.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "DreamcastArGun.hpp" 25 | 26 | DreamcastArGun::DreamcastArGun(uint8_t addr, 27 | uint32_t fd, 28 | std::shared_ptr scheduler, 29 | PlayerData playerData) : 30 | DreamcastPeripheral("AR gun", addr, fd, scheduler, playerData.playerIndex) 31 | {} 32 | 33 | DreamcastArGun::~DreamcastArGun() 34 | {} 35 | 36 | void DreamcastArGun::task(uint64_t currentTimeUs) 37 | {} 38 | 39 | void DreamcastArGun::txStarted(std::shared_ptr tx) 40 | {} 41 | 42 | void DreamcastArGun::txFailed(bool writeFailed, 43 | bool readFailed, 44 | std::shared_ptr tx) 45 | {} 46 | 47 | void DreamcastArGun::txComplete(std::shared_ptr packet, 48 | std::shared_ptr tx) 49 | {} 50 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastArGun.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "DreamcastPeripheral.hpp" 27 | #include "PlayerData.hpp" 28 | 29 | //! Handles communication with the Dreamcast AR gun peripheral 30 | class DreamcastArGun : public DreamcastPeripheral 31 | { 32 | public: 33 | //! Constructor 34 | //! @param[in] addr This peripheral's address 35 | //! @param[in] fd Function definition from the device info for this peripheral 36 | //! @param[in] scheduler The transmission scheduler this peripheral is to add to 37 | //! @param[in] playerData Data tied to player which controls this AR gun device 38 | DreamcastArGun(uint8_t addr, 39 | uint32_t fd, 40 | std::shared_ptr scheduler, 41 | PlayerData playerData); 42 | 43 | //! Virtual destructor 44 | virtual ~DreamcastArGun(); 45 | 46 | //! Inherited from DreamcastPeripheral 47 | virtual void task(uint64_t currentTimeUs) final; 48 | 49 | //! Called when transmission has been sent 50 | //! @param[in] tx The transmission that was sent 51 | virtual void txStarted(std::shared_ptr tx) final; 52 | 53 | //! Inherited from DreamcastPeripheral 54 | virtual void txFailed(bool writeFailed, 55 | bool readFailed, 56 | std::shared_ptr tx) final; 57 | 58 | //! Inherited from DreamcastPeripheral 59 | virtual void txComplete(std::shared_ptr packet, 60 | std::shared_ptr tx) final; 61 | 62 | //! Inherited from DreamcastPeripheral 63 | inline uint32_t getFunctionCode() override final 64 | { 65 | return FUNCTION_CODE; 66 | } 67 | 68 | public: 69 | //! Function code for AR gun 70 | static const uint32_t FUNCTION_CODE = DEVICE_FN_AR_GUN; 71 | 72 | private: 73 | }; 74 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastCamera.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "DreamcastCamera.hpp" 25 | 26 | DreamcastCamera::DreamcastCamera(uint8_t addr, 27 | uint32_t fd, 28 | std::shared_ptr scheduler, 29 | PlayerData playerData) : 30 | DreamcastPeripheral("camera", addr, fd, scheduler, playerData.playerIndex) 31 | {} 32 | 33 | DreamcastCamera::~DreamcastCamera() 34 | {} 35 | 36 | void DreamcastCamera::task(uint64_t currentTimeUs) 37 | {} 38 | 39 | void DreamcastCamera::txStarted(std::shared_ptr tx) 40 | {} 41 | 42 | void DreamcastCamera::txFailed(bool writeFailed, 43 | bool readFailed, 44 | std::shared_ptr tx) 45 | {} 46 | 47 | void DreamcastCamera::txComplete(std::shared_ptr packet, 48 | std::shared_ptr tx) 49 | {} 50 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastCamera.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "DreamcastPeripheral.hpp" 27 | #include "PlayerData.hpp" 28 | 29 | //! Handles communication with the Dreamcast camera peripheral 30 | class DreamcastCamera : public DreamcastPeripheral 31 | { 32 | public: 33 | //! Constructor 34 | //! @param[in] addr This peripheral's address 35 | //! @param[in] fd Function definition from the device info for this peripheral 36 | //! @param[in] scheduler The transmission scheduler this peripheral is to add to 37 | //! @param[in] playerData Data tied to player which controls this camera device 38 | DreamcastCamera(uint8_t addr, 39 | uint32_t fd, 40 | std::shared_ptr scheduler, 41 | PlayerData playerData); 42 | 43 | //! Virtual destructor 44 | virtual ~DreamcastCamera(); 45 | 46 | //! Inherited from DreamcastPeripheral 47 | virtual void task(uint64_t currentTimeUs) final; 48 | 49 | //! Called when transmission has been sent 50 | //! @param[in] tx The transmission that was sent 51 | virtual void txStarted(std::shared_ptr tx) final; 52 | 53 | //! Inherited from DreamcastPeripheral 54 | virtual void txFailed(bool writeFailed, 55 | bool readFailed, 56 | std::shared_ptr tx) final; 57 | 58 | //! Inherited from DreamcastPeripheral 59 | virtual void txComplete(std::shared_ptr packet, 60 | std::shared_ptr tx) final; 61 | 62 | //! Inherited from DreamcastPeripheral 63 | inline uint32_t getFunctionCode() override final 64 | { 65 | return FUNCTION_CODE; 66 | } 67 | 68 | public: 69 | //! Function code for camera 70 | static const uint32_t FUNCTION_CODE = DEVICE_FN_CAMERA; 71 | 72 | private: 73 | }; 74 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastExMedia.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "DreamcastExMedia.hpp" 25 | 26 | DreamcastExMedia::DreamcastExMedia(uint8_t addr, 27 | uint32_t fd, 28 | std::shared_ptr scheduler, 29 | PlayerData playerData) : 30 | DreamcastPeripheral("exmedia", addr, fd, scheduler, playerData.playerIndex) 31 | {} 32 | 33 | DreamcastExMedia::~DreamcastExMedia() 34 | {} 35 | 36 | void DreamcastExMedia::task(uint64_t currentTimeUs) 37 | {} 38 | 39 | void DreamcastExMedia::txStarted(std::shared_ptr tx) 40 | {} 41 | 42 | void DreamcastExMedia::txFailed(bool writeFailed, 43 | bool readFailed, 44 | std::shared_ptr tx) 45 | {} 46 | 47 | void DreamcastExMedia::txComplete(std::shared_ptr packet, 48 | std::shared_ptr tx) 49 | {} 50 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastExMedia.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "DreamcastPeripheral.hpp" 27 | #include "PlayerData.hpp" 28 | 29 | //! Handles communication with the Dreamcast media peripheral 30 | class DreamcastExMedia : public DreamcastPeripheral 31 | { 32 | public: 33 | //! Constructor 34 | //! @param[in] addr This peripheral's address 35 | //! @param[in] fd Function definition from the device info for this peripheral 36 | //! @param[in] scheduler The transmission scheduler this peripheral is to add to 37 | //! @param[in] playerData Data tied to player which controls this media device 38 | DreamcastExMedia(uint8_t addr, 39 | uint32_t fd, 40 | std::shared_ptr scheduler, 41 | PlayerData playerData); 42 | 43 | //! Virtual destructor 44 | virtual ~DreamcastExMedia(); 45 | 46 | //! Inherited from DreamcastPeripheral 47 | virtual void task(uint64_t currentTimeUs) final; 48 | 49 | //! Called when transmission has been sent 50 | //! @param[in] tx The transmission that was sent 51 | virtual void txStarted(std::shared_ptr tx) final; 52 | 53 | //! Inherited from DreamcastPeripheral 54 | virtual void txFailed(bool writeFailed, 55 | bool readFailed, 56 | std::shared_ptr tx) final; 57 | 58 | //! Inherited from DreamcastPeripheral 59 | virtual void txComplete(std::shared_ptr packet, 60 | std::shared_ptr tx) final; 61 | 62 | //! Inherited from DreamcastPeripheral 63 | inline uint32_t getFunctionCode() override final 64 | { 65 | return FUNCTION_CODE; 66 | } 67 | 68 | public: 69 | //! Function code for external media 70 | static const uint32_t FUNCTION_CODE = DEVICE_FN_EXMEDIA; 71 | 72 | private: 73 | }; 74 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastGun.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "DreamcastGun.hpp" 25 | 26 | DreamcastGun::DreamcastGun(uint8_t addr, 27 | uint32_t fd, 28 | std::shared_ptr scheduler, 29 | PlayerData playerData) : 30 | DreamcastPeripheral("gun", addr, fd, scheduler, playerData.playerIndex) 31 | {} 32 | 33 | DreamcastGun::~DreamcastGun() 34 | {} 35 | 36 | void DreamcastGun::task(uint64_t currentTimeUs) 37 | {} 38 | 39 | void DreamcastGun::txStarted(std::shared_ptr tx) 40 | {} 41 | 42 | void DreamcastGun::txFailed(bool writeFailed, 43 | bool readFailed, 44 | std::shared_ptr tx) 45 | {} 46 | 47 | void DreamcastGun::txComplete(std::shared_ptr packet, 48 | std::shared_ptr tx) 49 | {} 50 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastGun.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "DreamcastPeripheral.hpp" 27 | #include "PlayerData.hpp" 28 | 29 | //! Handles communication with the Dreamcast gun peripheral 30 | class DreamcastGun : public DreamcastPeripheral 31 | { 32 | public: 33 | //! Constructor 34 | //! @param[in] addr This peripheral's address 35 | //! @param[in] fd Function definition from the device info for this peripheral 36 | //! @param[in] scheduler The transmission scheduler this peripheral is to add to 37 | //! @param[in] playerData Data tied to player which controls this gun device 38 | DreamcastGun(uint8_t addr, 39 | uint32_t fd, 40 | std::shared_ptr scheduler, 41 | PlayerData playerData); 42 | 43 | //! Virtual destructor 44 | virtual ~DreamcastGun(); 45 | 46 | //! Inherited from DreamcastPeripheral 47 | virtual void task(uint64_t currentTimeUs) final; 48 | 49 | //! Called when transmission has been sent 50 | //! @param[in] tx The transmission that was sent 51 | virtual void txStarted(std::shared_ptr tx) final; 52 | 53 | //! Inherited from DreamcastPeripheral 54 | virtual void txFailed(bool writeFailed, 55 | bool readFailed, 56 | std::shared_ptr tx) final; 57 | 58 | //! Inherited from DreamcastPeripheral 59 | virtual void txComplete(std::shared_ptr packet, 60 | std::shared_ptr tx) final; 61 | 62 | //! Inherited from DreamcastPeripheral 63 | inline uint32_t getFunctionCode() override final 64 | { 65 | return FUNCTION_CODE; 66 | } 67 | 68 | public: 69 | //! Function code for gun 70 | static const uint32_t FUNCTION_CODE = DEVICE_FN_GUN; 71 | 72 | private: 73 | }; 74 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastKeyboard.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "DreamcastKeyboard.hpp" 25 | 26 | DreamcastKeyboard::DreamcastKeyboard(uint8_t addr, 27 | uint32_t fd, 28 | std::shared_ptr scheduler, 29 | PlayerData playerData) : 30 | DreamcastPeripheral("keyboard", addr, fd, scheduler, playerData.playerIndex) 31 | {} 32 | 33 | DreamcastKeyboard::~DreamcastKeyboard() 34 | {} 35 | 36 | void DreamcastKeyboard::task(uint64_t currentTimeUs) 37 | {} 38 | 39 | void DreamcastKeyboard::txStarted(std::shared_ptr tx) 40 | {} 41 | 42 | void DreamcastKeyboard::txFailed(bool writeFailed, 43 | bool readFailed, 44 | std::shared_ptr tx) 45 | {} 46 | 47 | void DreamcastKeyboard::txComplete(std::shared_ptr packet, 48 | std::shared_ptr tx) 49 | {} 50 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastKeyboard.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "DreamcastPeripheral.hpp" 27 | #include "PlayerData.hpp" 28 | 29 | //! Handles communication with the Dreamcast keyboard peripheral 30 | class DreamcastKeyboard : public DreamcastPeripheral 31 | { 32 | public: 33 | //! Constructor 34 | //! @param[in] addr This peripheral's address 35 | //! @param[in] fd Function definition from the device info for this peripheral 36 | //! @param[in] scheduler The transmission scheduler this peripheral is to add to 37 | //! @param[in] playerData Data tied to player which controls this keyboard device 38 | DreamcastKeyboard(uint8_t addr, 39 | uint32_t fd, 40 | std::shared_ptr scheduler, 41 | PlayerData playerData); 42 | 43 | //! Virtual destructor 44 | virtual ~DreamcastKeyboard(); 45 | 46 | //! Inherited from DreamcastPeripheral 47 | virtual void task(uint64_t currentTimeUs) final; 48 | 49 | //! Called when transmission has been sent 50 | //! @param[in] tx The transmission that was sent 51 | virtual void txStarted(std::shared_ptr tx) final; 52 | 53 | //! Inherited from DreamcastPeripheral 54 | virtual void txFailed(bool writeFailed, 55 | bool readFailed, 56 | std::shared_ptr tx) final; 57 | 58 | //! Inherited from DreamcastPeripheral 59 | virtual void txComplete(std::shared_ptr packet, 60 | std::shared_ptr tx) final; 61 | 62 | //! Inherited from DreamcastPeripheral 63 | inline uint32_t getFunctionCode() override final 64 | { 65 | return FUNCTION_CODE; 66 | } 67 | 68 | public: 69 | //! Function code for keyboard 70 | static const uint32_t FUNCTION_CODE = DEVICE_FN_KEYBOARD; 71 | 72 | private: 73 | }; 74 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastMicrophone.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "DreamcastMicrophone.hpp" 25 | 26 | DreamcastMicrophone::DreamcastMicrophone(uint8_t addr, 27 | uint32_t fd, 28 | std::shared_ptr scheduler, 29 | PlayerData playerData) : 30 | DreamcastPeripheral("microphone", addr, fd, scheduler, playerData.playerIndex) 31 | {} 32 | 33 | DreamcastMicrophone::~DreamcastMicrophone() 34 | {} 35 | 36 | void DreamcastMicrophone::task(uint64_t currentTimeUs) 37 | {} 38 | 39 | void DreamcastMicrophone::txStarted(std::shared_ptr tx) 40 | {} 41 | 42 | void DreamcastMicrophone::txFailed(bool writeFailed, 43 | bool readFailed, 44 | std::shared_ptr tx) 45 | {} 46 | 47 | void DreamcastMicrophone::txComplete(std::shared_ptr packet, 48 | std::shared_ptr tx) 49 | {} 50 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastMicrophone.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "DreamcastPeripheral.hpp" 27 | #include "PlayerData.hpp" 28 | 29 | //! Handles communication with the Dreamcast microphone peripheral 30 | class DreamcastMicrophone : public DreamcastPeripheral 31 | { 32 | public: 33 | //! Constructor 34 | //! @param[in] addr This peripheral's address 35 | //! @param[in] fd Function definition from the device info for this peripheral 36 | //! @param[in] scheduler The transmission scheduler this peripheral is to add to 37 | //! @param[in] playerData Data tied to player which controls this microphone device 38 | DreamcastMicrophone(uint8_t addr, 39 | uint32_t fd, 40 | std::shared_ptr scheduler, 41 | PlayerData playerData); 42 | 43 | //! Virtual destructor 44 | virtual ~DreamcastMicrophone(); 45 | 46 | //! Inherited from DreamcastPeripheral 47 | virtual void task(uint64_t currentTimeUs) final; 48 | 49 | //! Called when transmission has been sent 50 | //! @param[in] tx The transmission that was sent 51 | virtual void txStarted(std::shared_ptr tx) final; 52 | 53 | //! Inherited from DreamcastPeripheral 54 | virtual void txFailed(bool writeFailed, 55 | bool readFailed, 56 | std::shared_ptr tx) final; 57 | 58 | //! Inherited from DreamcastPeripheral 59 | virtual void txComplete(std::shared_ptr packet, 60 | std::shared_ptr tx) final; 61 | 62 | //! Inherited from DreamcastPeripheral 63 | inline uint32_t getFunctionCode() override final 64 | { 65 | return FUNCTION_CODE; 66 | } 67 | 68 | public: 69 | //! Function code for microphone 70 | static const uint32_t FUNCTION_CODE = DEVICE_FN_AUDIO_INPUT; 71 | 72 | private: 73 | }; 74 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastMouse.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "DreamcastMouse.hpp" 25 | 26 | DreamcastMouse::DreamcastMouse(uint8_t addr, 27 | uint32_t fd, 28 | std::shared_ptr scheduler, 29 | PlayerData playerData) : 30 | DreamcastPeripheral("mouse", addr, fd, scheduler, playerData.playerIndex) 31 | {} 32 | 33 | DreamcastMouse::~DreamcastMouse() 34 | {} 35 | 36 | void DreamcastMouse::task(uint64_t currentTimeUs) 37 | {} 38 | 39 | void DreamcastMouse::txStarted(std::shared_ptr tx) 40 | {} 41 | 42 | void DreamcastMouse::txFailed(bool writeFailed, 43 | bool readFailed, 44 | std::shared_ptr tx) 45 | {} 46 | 47 | void DreamcastMouse::txComplete(std::shared_ptr packet, 48 | std::shared_ptr tx) 49 | {} 50 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastMouse.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "DreamcastPeripheral.hpp" 27 | #include "PlayerData.hpp" 28 | 29 | //! Handles communication with the Dreamcast mouse peripheral 30 | class DreamcastMouse : public DreamcastPeripheral 31 | { 32 | public: 33 | //! Constructor 34 | //! @param[in] addr This peripheral's address 35 | //! @param[in] fd Function definition from the device info for this peripheral 36 | //! @param[in] scheduler The transmission scheduler this peripheral is to add to 37 | //! @param[in] playerData Data tied to player which controls this mouse device 38 | DreamcastMouse(uint8_t addr, 39 | uint32_t fd, 40 | std::shared_ptr scheduler, 41 | PlayerData playerData); 42 | 43 | //! Virtual destructor 44 | virtual ~DreamcastMouse(); 45 | 46 | //! Inherited from DreamcastPeripheral 47 | virtual void task(uint64_t currentTimeUs) final; 48 | 49 | //! Called when transmission has been sent 50 | //! @param[in] tx The transmission that was sent 51 | virtual void txStarted(std::shared_ptr tx) final; 52 | 53 | //! Inherited from DreamcastPeripheral 54 | virtual void txFailed(bool writeFailed, 55 | bool readFailed, 56 | std::shared_ptr tx) final; 57 | 58 | //! Inherited from DreamcastPeripheral 59 | virtual void txComplete(std::shared_ptr packet, 60 | std::shared_ptr tx) final; 61 | 62 | //! Inherited from DreamcastPeripheral 63 | inline uint32_t getFunctionCode() override final 64 | { 65 | return FUNCTION_CODE; 66 | } 67 | 68 | public: 69 | //! Function code for mouse 70 | static const uint32_t FUNCTION_CODE = DEVICE_FN_MOUSE; 71 | 72 | private: 73 | }; 74 | -------------------------------------------------------------------------------- /src/hostLib/peripherals/DreamcastTimer.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "DreamcastTimer.hpp" 25 | #include 26 | 27 | DreamcastTimer::DreamcastTimer(uint8_t addr, 28 | uint32_t fd, 29 | std::shared_ptr scheduler, 30 | PlayerData playerData) : 31 | DreamcastPeripheral("timer", addr, fd, scheduler, playerData.playerIndex), 32 | mGamepad(playerData.gamepad), 33 | mButtonStatusId(0) 34 | { 35 | // Poll only the upper VMU button states 36 | if (addr & SUB_PERIPHERAL_ADDR_START_MASK) 37 | { 38 | uint32_t payload = FUNCTION_CODE; 39 | mButtonStatusId = mEndpointTxScheduler->add( 40 | PrioritizedTxScheduler::TX_TIME_ASAP, 41 | this, 42 | COMMAND_GET_CONDITION, 43 | &payload, 44 | 1, 45 | true, 46 | 2, 47 | BUTTON_POLL_PERIOD_US); 48 | } 49 | } 50 | 51 | DreamcastTimer::~DreamcastTimer() 52 | {} 53 | 54 | void DreamcastTimer::task(uint64_t currentTimeUs) 55 | {} 56 | 57 | void DreamcastTimer::txStarted(std::shared_ptr tx) 58 | {} 59 | 60 | void DreamcastTimer::txFailed(bool writeFailed, 61 | bool readFailed, 62 | std::shared_ptr tx) 63 | {} 64 | 65 | void DreamcastTimer::txComplete(std::shared_ptr packet, 66 | std::shared_ptr tx) 67 | { 68 | if (tx->transmissionId == mButtonStatusId 69 | && packet->frame.command == COMMAND_RESPONSE_DATA_XFER 70 | && packet->payload.size() >= 2) 71 | { 72 | // Set controller! 73 | const uint8_t cond = packet->payload[1] >> COND_RIGHT_SHIFT; 74 | DreamcastControllerObserver::SecondaryControllerCondition secondaryCondition; 75 | memcpy(&secondaryCondition, &cond, 1); 76 | mGamepad.setSecondaryControllerCondition(secondaryCondition); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/hostLib/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | file(GLOB SRC "${CMAKE_CURRENT_SOURCE_DIR}/*.c*") 6 | 7 | add_library(testHostLib STATIC ${SRC}) 8 | 9 | target_link_libraries(testHostLib 10 | PUBLIC 11 | hostLib 12 | gtest_main 13 | gmock_main 14 | ) 15 | 16 | target_include_directories(testHostLib 17 | PUBLIC 18 | "$" 19 | "$" 20 | "${PROJECT_SOURCE_DIR}/inc" 21 | "${CMAKE_CURRENT_LIST_DIR}/mocks") 22 | -------------------------------------------------------------------------------- /src/hostLib/test/mocks/MockClock.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "hal/System/ClockInterface.hpp" 27 | 28 | #include 29 | #include 30 | 31 | class MockClock : public ClockInterface 32 | { 33 | public: 34 | MOCK_METHOD(uint64_t, getTimeUs, (), (const, override)); 35 | }; 36 | -------------------------------------------------------------------------------- /src/hostLib/test/mocks/MockCommandParser.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | class MockCommandParser : public CommandParser 32 | { 33 | public: 34 | MockCommandParser() = default; 35 | virtual ~MockCommandParser() = default; 36 | 37 | MOCK_METHOD(const char*, getCommandChars, (), (override)); 38 | MOCK_METHOD(void, submit, (const char* chars, uint32_t len), (override)); 39 | MOCK_METHOD(void, printHelp, (), (override)); 40 | }; 41 | -------------------------------------------------------------------------------- /src/hostLib/test/mocks/MockDreamcastControllerObserver.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "hal/Usb/DreamcastControllerObserver.hpp" 27 | 28 | #include 29 | #include 30 | 31 | class MockDreamcastControllerObserver : public DreamcastControllerObserver 32 | { 33 | public: 34 | MOCK_METHOD(void, setControllerCondition, (const ControllerCondition& controllerCondition), (override)); 35 | 36 | MOCK_METHOD(void, controllerConnected, (), (override)); 37 | 38 | MOCK_METHOD(void, controllerDisconnected, (), (override)); 39 | 40 | MOCK_METHOD(void, setSecondaryControllerCondition, 41 | (const SecondaryControllerCondition& secondaryControllerCondition), (override)); 42 | 43 | MOCK_METHOD(void, setChangeCondition, (bool changeSignal), (override)); 44 | }; 45 | -------------------------------------------------------------------------------- /src/hostLib/test/mocks/MockDreamcastPeripheral.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "DreamcastPeripheral.hpp" 27 | 28 | #include 29 | #include 30 | 31 | class MockDreamcastPeripheral : public DreamcastPeripheral 32 | { 33 | public: 34 | MockDreamcastPeripheral(uint8_t addr, 35 | uint32_t fd, 36 | std::shared_ptr scheduler, 37 | uint32_t playerIndex) : 38 | DreamcastPeripheral("mock", addr, fd, scheduler, playerIndex) 39 | {} 40 | 41 | MOCK_METHOD(void, txStarted, (std::shared_ptr tx), (override)); 42 | 43 | MOCK_METHOD(void, 44 | txFailed, 45 | (bool writeFailed, 46 | bool readFailed, 47 | std::shared_ptr tx), 48 | (override)); 49 | 50 | MOCK_METHOD(void, 51 | txComplete, 52 | (std::shared_ptr packet, 53 | std::shared_ptr tx), 54 | (override)); 55 | 56 | MOCK_METHOD(void, task, (uint64_t currentTimeUs), (override)); 57 | 58 | MOCK_METHOD(uint32_t, getFunctionCode, (), (override)); 59 | }; 60 | -------------------------------------------------------------------------------- /src/hostLib/test/mocks/MockMapleBus.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "hal/MapleBus/MapleBusInterface.hpp" 27 | #include "hal/MapleBus/MaplePacket.hpp" 28 | 29 | #include 30 | #include 31 | 32 | class MockMapleBus : public MapleBusInterface 33 | { 34 | public: 35 | virtual bool write(const MaplePacket& packet, 36 | bool autostartRead, 37 | uint64_t readTimeoutUs=MAPLE_RESPONSE_TIMEOUT_US) override 38 | { 39 | return mockWrite(packet, autostartRead, readTimeoutUs); 40 | } 41 | 42 | MOCK_METHOD( 43 | bool, 44 | mockWrite, 45 | ( 46 | const MaplePacket& packet, 47 | bool expectResponse, 48 | uint64_t readTimeoutUs 49 | ) 50 | ); 51 | 52 | MOCK_METHOD(Status, processEvents, (uint64_t currentTimeUs), (override)); 53 | 54 | MOCK_METHOD(bool, isBusy, (), (override)); 55 | 56 | MOCK_METHOD(bool, startRead, (uint64_t readTimeoutUs), (override)); 57 | }; 58 | -------------------------------------------------------------------------------- /src/hostLib/test/mocks/MockMutex.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "hal/System/MutexInterface.hpp" 27 | 28 | #include 29 | #include 30 | 31 | class MockMutex : public MutexInterface 32 | { 33 | public: 34 | MOCK_METHOD(void, lock, (), (override)); 35 | 36 | MOCK_METHOD(void, unlock, (), (override)); 37 | 38 | MOCK_METHOD(int8_t, tryLock, (), (override)); 39 | }; 40 | -------------------------------------------------------------------------------- /src/hostLib/test/mocks/MockUsbFileSystem.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "hal/Usb/UsbFileSystem.hpp" 27 | 28 | #include 29 | #include 30 | 31 | class MockUsbFileSystem : public UsbFileSystem 32 | { 33 | public: 34 | MOCK_METHOD(void, add, (UsbFile* file), (override)); 35 | MOCK_METHOD(void, remove, (UsbFile* file), (override)); 36 | }; 37 | -------------------------------------------------------------------------------- /src/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | add_subdirectory(Client) 6 | add_subdirectory(Host) 7 | -------------------------------------------------------------------------------- /src/main/Client/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | file(GLOB COMMON_SRC "${CMAKE_CURRENT_SOURCE_DIR}/common/*.c*") 6 | 7 | add_executable(client-with-usb-host "${CMAKE_CURRENT_SOURCE_DIR}/client_usb_host.cpp" "${COMMON_SRC}") 8 | pico_add_extra_outputs(client-with-usb-host) 9 | pico_set_binary_type(client-with-usb-host copy_to_ram) 10 | target_link_libraries(client-with-usb-host 11 | PRIVATE 12 | pico_multicore 13 | hal-MapleBus 14 | hal-System 15 | hal-Usb-Host 16 | clientLib 17 | pico_stdlib 18 | ) 19 | target_compile_options(client-with-usb-host PRIVATE 20 | -Wall 21 | #-Werror 22 | -O3 23 | ) 24 | 25 | target_include_directories(client-with-usb-host 26 | PRIVATE 27 | "$" 28 | "$" 29 | "${PROJECT_SOURCE_DIR}/inc" 30 | "${CMAKE_CURRENT_SOURCE_DIR}/common") 31 | -------------------------------------------------------------------------------- /src/main/Client/I2cDevice.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | 28 | class I2cDevice 29 | { 30 | public: 31 | //! Virtual destrictor 32 | virtual ~I2cDevice() {} 33 | 34 | //! @returns the address of this I2C device 35 | virtual uint8_t getAddress() = 0; 36 | 37 | //! @param[out] byte Set to the next byte to send 38 | //! @param[out] sendStop Send stop after this byte, send start on next 39 | //! @returns false if this is the last byte in this sequence 40 | //! @returns true if there is another byte queued for this sequence 41 | virtual bool nextByteOut(uint8_t& byte, bool& sendStop) = 0; 42 | 43 | //! @returns true when data is ready for write 44 | virtual bool isOutAvailable() = 0; 45 | 46 | //! Called to notify the device that write failed for the current sequence. 47 | //! The device is expected to purge its output buffer and optionally start over. 48 | //! @param[in] abortReason The reason write failed (see I2C_IC_TX_ABRT_SOURCE definitions) 49 | virtual void writeFailed(uint32_t abortReason) = 0; 50 | 51 | //! @param[in] byte The byte that was read off of the bus 52 | //! @returns false if this is the last byte to be read 53 | //! @returns true if another byte is expected 54 | virtual void nextByteIn(uint8_t byte) = 0; 55 | 56 | //! @returns number of bytes to read when input is expected or 0 57 | virtual uint32_t isInExpected() = 0; 58 | 59 | //! Called to notify the device that read failed for the current sequence. 60 | //! The device is expected to purge its input buffer and optionally start over. 61 | //! @param[in] abortReason The reason read failed (see I2C_IC_TX_ABRT_SOURCE definitions) 62 | virtual void readFailed(uint32_t abortReason) = 0; 63 | }; 64 | -------------------------------------------------------------------------------- /src/main/Client/I2cDriver.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include "I2cDevice.hpp" 27 | 28 | #include "hardware/i2c.h" 29 | 30 | #include 31 | #include 32 | 33 | class I2cDriver 34 | { 35 | public: 36 | enum class State 37 | { 38 | NONE = 0, 39 | READING, 40 | WRITING 41 | }; 42 | 43 | I2cDriver(uint32_t i2cIdx, uint32_t baud, uint32_t gpioStart); 44 | 45 | void addDevice(I2cDevice* device); 46 | 47 | //! Does an iterative process of I2C activity 48 | //! @returns true iff some activity was performed after this call 49 | bool process(); 50 | 51 | //! Processes until idle 52 | //! @param[in] timeoutMs Maximum number of milliseconds to wait or -1 to wait until complete; 53 | //! flush(0) is the same as calling process() 54 | void flush(int32_t timeoutMs=-1); 55 | 56 | bool checkForAbort(); 57 | 58 | void start(std::list::iterator iter); 59 | 60 | void end(); 61 | 62 | public: 63 | static i2c_inst_t* const I2C_INSTANCES[2]; 64 | 65 | private: 66 | i2c_inst_t* const mI2c; 67 | std::list mDeviceList; 68 | uint8_t mProcAddr; 69 | I2cDevice* mProcDevice; 70 | State mProcState; 71 | bool mWriteComplete; 72 | uint32_t mNumRead; 73 | uint32_t mNumReadWaiting; 74 | bool mFirstByte; 75 | }; 76 | -------------------------------------------------------------------------------- /src/main/Client/common/led.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "led.hpp" 25 | 26 | #include "configuration.h" 27 | 28 | #include "pico/stdlib.h" 29 | 30 | // Only a single LED function for client 31 | #define CLIENT_LED_PIN ((USB_LED_PIN >= 0) ? USB_LED_PIN : SIMPLE_USB_LED_PIN) 32 | 33 | void led_init() 34 | { 35 | if (CLIENT_LED_PIN >= 0) 36 | { 37 | gpio_init(CLIENT_LED_PIN); 38 | gpio_set_dir_out_masked(1< activityStopTime) 57 | { 58 | activityStopTime = lastActivityTimeUs; 59 | } 60 | } 61 | 62 | if (activityStopTime > currentTime) 63 | { 64 | uint64_t t = currentTime - startUs; 65 | if (t >= BLINK_TIME_US) 66 | { 67 | startUs += BLINK_TIME_US; 68 | ledOn = !ledOn; 69 | } 70 | } 71 | else 72 | { 73 | startUs = currentTime; 74 | ledOn = true; 75 | } 76 | 77 | gpio_put(CLIENT_LED_PIN, ledOn); 78 | } 79 | -------------------------------------------------------------------------------- /src/main/Client/common/led.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #pragma once 25 | 26 | #include 27 | 28 | void led_init(); 29 | void led_task(uint64_t lastActivityTimeUs); 30 | -------------------------------------------------------------------------------- /src/main/Host/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | file(GLOB HOST_SRC "${CMAKE_CURRENT_SOURCE_DIR}/host*.c*") 6 | 7 | if (${PICO_BOARD} STREQUAL "pico2") 8 | # Increase the CPU frequency to 150MHz for the pico2 board 9 | add_definitions(-DCPU_FREQ_KHZ=150000) 10 | endif() 11 | 12 | # 13 | # host-4p 14 | # 15 | 16 | add_executable(host-4p ${HOST_SRC}) 17 | pico_add_extra_outputs(host-4p) 18 | target_link_libraries(host-4p 19 | PRIVATE 20 | pico_multicore 21 | hal-MapleBus 22 | hal-System 23 | hal-Usb-Client 24 | pico_stdio_usb 25 | hostLib 26 | ) 27 | target_compile_options(host-4p PRIVATE 28 | -Wall 29 | -Werror 30 | -O3 31 | ) 32 | target_compile_definitions(host-4p PUBLIC SELECTED_NUMBER_OF_DEVICES=4) 33 | 34 | target_include_directories(host-4p 35 | PRIVATE 36 | "$" 37 | "$" 38 | "${PROJECT_SOURCE_DIR}/inc") 39 | 40 | # 41 | # host-2p 42 | # 43 | 44 | add_executable(host-2p ${HOST_SRC}) 45 | pico_add_extra_outputs(host-2p) 46 | target_link_libraries(host-2p 47 | PRIVATE 48 | pico_multicore 49 | hal-MapleBus 50 | hal-System 51 | hal-Usb-Client 52 | pico_stdio_usb 53 | hostLib 54 | ) 55 | target_compile_options(host-2p PRIVATE 56 | -Wall 57 | -Werror 58 | -O3 59 | ) 60 | target_compile_definitions(host-2p PUBLIC SELECTED_NUMBER_OF_DEVICES=2) 61 | 62 | target_include_directories(host-2p 63 | PRIVATE 64 | "$" 65 | "$" 66 | "${PROJECT_SOURCE_DIR}/inc") 67 | 68 | # 69 | # host-1p 70 | # 71 | 72 | add_executable(host-1p ${HOST_SRC}) 73 | pico_add_extra_outputs(host-1p) 74 | target_link_libraries(host-1p 75 | PRIVATE 76 | pico_multicore 77 | hal-MapleBus 78 | hal-System 79 | hal-Usb-Client 80 | pico_stdio_usb 81 | hostLib 82 | ) 83 | target_compile_options(host-1p PRIVATE 84 | -Wall 85 | -Werror 86 | -O3 87 | ) 88 | target_compile_definitions(host-1p PUBLIC SELECTED_NUMBER_OF_DEVICES=1) 89 | 90 | target_include_directories(host-1p 91 | PRIVATE 92 | "$" 93 | "$" 94 | "${PROJECT_SOURCE_DIR}/inc") 95 | 96 | 97 | # 98 | # zero_host-4p 99 | # 100 | 101 | if ("${PICO_BOARD}" STREQUAL "pico") 102 | 103 | add_executable(zero_host-4p ${HOST_SRC}) 104 | pico_add_extra_outputs(zero_host-4p) 105 | target_link_libraries(zero_host-4p 106 | PRIVATE 107 | pico_multicore 108 | hal-MapleBus 109 | hal-System 110 | hal-Usb-Client 111 | pico_stdio_usb 112 | hostLib 113 | ) 114 | target_compile_options(zero_host-4p PRIVATE 115 | -Wall 116 | -Werror 117 | -O3 118 | ) 119 | target_compile_definitions(zero_host-4p 120 | PUBLIC 121 | SELECTED_NUMBER_OF_DEVICES=4 122 | P3_BUS_START_PIN=2 123 | P4_BUS_START_PIN=4 124 | ) 125 | 126 | target_include_directories(zero_host-4p 127 | PRIVATE 128 | "$" 129 | "$" 130 | "${PROJECT_SOURCE_DIR}/inc") 131 | 132 | endif() 133 | -------------------------------------------------------------------------------- /src/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | set(CMAKE_VERBOSE_MAKEFILE ON) 4 | 5 | # Specify the commit you depend on and update it regularly. 6 | set(GOOGLE_TEST_COMMIT_ID "4219e7254cb8c473f57f6065bd13d1520d7b708f") 7 | include(FetchContent) 8 | FetchContent_Declare( 9 | googletest 10 | URL "https://github.com/google/googletest/archive/${GOOGLE_TEST_COMMIT_ID}.zip" 11 | ) 12 | FetchContent_MakeAvailable(googletest) 13 | 14 | file(GLOB SRC "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.c") 15 | add_executable(testExe 16 | ${SRC} 17 | ) 18 | target_link_libraries(testExe 19 | PRIVATE 20 | gtest_main 21 | gmock_main 22 | pthread 23 | -Wl,--whole-archive 24 | testHostLib 25 | -Wl,--no-whole-archive 26 | ) 27 | 28 | target_include_directories(testExe 29 | PRIVATE 30 | "$" 31 | "$" 32 | "${PROJECT_SOURCE_DIR}/inc" 33 | "${CMAKE_CURRENT_LIST_DIR}/mocks") 34 | 35 | enable_testing() 36 | add_test(NAME all_tests COMMAND testExe) 37 | add_custom_target(test 38 | COMMAND ${CMAKE_CTEST_COMMAND} --force-new-ctest-process --verbose --output-on-failure 39 | DEPENDS testExe) 40 | -------------------------------------------------------------------------------- /src/test/main.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2022-2025 James Smith of OrangeFox86 4 | // https://github.com/OrangeFox86/DreamcastControllerUsbPico 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include 25 | #include 26 | 27 | int main(int argc, char **argv) 28 | { 29 | ::testing::InitGoogleTest(&argc, argv); 30 | return RUN_ALL_TESTS(); 31 | } 32 | -------------------------------------------------------------------------------- /very_clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -rf build 4 | rm -rf build-pico 5 | rm -rf build-pico_w 6 | rm -rf build-pico2 7 | rm -rf build-pico2_w 8 | rm -rf build-test 9 | rm -rf dist 10 | --------------------------------------------------------------------------------