mirror of
https://github.com/dschmenk/apple2pi.git
synced 2024-11-24 12:31:30 +00:00
Added emulation of Apple2Pi card v6.x based on Raspberry Pi Pico - see https://github.com/a2retrosystems/A2retroNET
The Raspberry Pi Pico is connected to the Linux computer via its USB port, so every Linux computer with USB 1.1 ACM CDC virtual serial port (usually exposed as /dev/ttyACM0) support can be used. For the Apple2Pi card v6.x see https://youtu.be/WHq4d5E-5p8?t=1083
This commit is contained in:
parent
f9b513a838
commit
6951ff78d7
27
pipico/CMakeLists.txt
Normal file
27
pipico/CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
set(PROJECT_NAME Apple-II-Pi)
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
|
||||||
|
include(pico_sdk_import.cmake)
|
||||||
|
pico_sdk_init()
|
||||||
|
|
||||||
|
project(${PROJECT_NAME} C CXX ASM)
|
||||||
|
add_executable(${PROJECT_NAME})
|
||||||
|
pico_add_extra_outputs(${PROJECT_NAME})
|
||||||
|
|
||||||
|
pico_enable_stdio_uart(${PROJECT_NAME} 0)
|
||||||
|
pico_enable_stdio_usb(${PROJECT_NAME} 1)
|
||||||
|
|
||||||
|
pico_generate_pio_header(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}/bus.pio)
|
||||||
|
|
||||||
|
target_sources(${PROJECT_NAME} PRIVATE
|
||||||
|
main.c
|
||||||
|
board.c
|
||||||
|
incbin.S
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||||
|
pico_stdlib
|
||||||
|
pico_multicore
|
||||||
|
hardware_pio
|
||||||
|
)
|
21
pipico/LICENSE
Normal file
21
pipico/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Oliver Schmidt (https://a2retro.de/)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
93
pipico/board.c
Normal file
93
pipico/board.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Oliver Schmidt (https://a2retro.de/)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bus.pio.h"
|
||||||
|
|
||||||
|
extern const __attribute__((aligned(4))) uint8_t firmware[];
|
||||||
|
|
||||||
|
static bool __not_in_flash( "active") active;
|
||||||
|
static uint32_t __not_in_flash("command") command;
|
||||||
|
static uint32_t __not_in_flash("control") control;
|
||||||
|
|
||||||
|
void __not_in_flash_func(board)() {
|
||||||
|
while (true) {
|
||||||
|
uint32_t enbl = pio_sm_get_blocking(pio0, sm_enbl);
|
||||||
|
uint32_t addr = enbl & 0x0FFF;
|
||||||
|
uint32_t io = enbl & 0x0F00; // IOSTRB or IOSEL
|
||||||
|
uint32_t strb = enbl & 0x0800; // IOSTRB
|
||||||
|
uint32_t read = enbl & 0x1000; // R/W
|
||||||
|
|
||||||
|
if (addr == 0x0FFF) {
|
||||||
|
active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read) {
|
||||||
|
if (!io) { // DEVSEL
|
||||||
|
switch (addr & 0xF) {
|
||||||
|
case 0x8:
|
||||||
|
pio_sm_put(pio0, sm_read, sio_hw->fifo_rd);
|
||||||
|
break;
|
||||||
|
case 0x9:
|
||||||
|
// SIO_FIFO_ST_VLD_BITS _u(0x00000001)
|
||||||
|
// SIO_FIFO_ST_RDY_BITS _u(0x00000002)
|
||||||
|
pio_sm_put(pio0, sm_read, (sio_hw->fifo_st & 3) << 3);
|
||||||
|
break;
|
||||||
|
case 0xA:
|
||||||
|
pio_sm_put(pio0, sm_read, command);
|
||||||
|
break;
|
||||||
|
case 0xB:
|
||||||
|
pio_sm_put(pio0, sm_read, control);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!strb || active) {
|
||||||
|
pio_sm_put(pio0, sm_read, firmware[addr]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uint32_t data = pio_sm_get_blocking(pio0, sm_write);
|
||||||
|
if (!io) { // DEVSEL
|
||||||
|
switch (addr & 0xF) {
|
||||||
|
case 0x8:
|
||||||
|
sio_hw->fifo_wr = data;
|
||||||
|
break;
|
||||||
|
case 0xA:
|
||||||
|
command = data;
|
||||||
|
break;
|
||||||
|
case 0xB:
|
||||||
|
control = data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (io && !strb) {
|
||||||
|
active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_put(gpio_led, active);
|
||||||
|
}
|
||||||
|
}
|
206
pipico/bus.pio
Normal file
206
pipico/bus.pio
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Oliver Schmidt (https://a2retro.de/)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
.define public gpio_addr 2 // 12 pins
|
||||||
|
.define public gpio_rw 14
|
||||||
|
.define public gpio_data 15 // 8 pins
|
||||||
|
.define public gpio_led 25
|
||||||
|
.define public gpio_enbl 26 // DEVSEL | IOSEL | IOSTRB
|
||||||
|
.define public gpio_irq 27
|
||||||
|
.define public gpio_rdy 28
|
||||||
|
|
||||||
|
.define public size_addr 13 // incl. R/W
|
||||||
|
.define public size_data 8
|
||||||
|
|
||||||
|
.define public sm_enbl 0
|
||||||
|
.define public sm_read 1 // from Apple II perspective
|
||||||
|
.define public sm_write 2 // from Apple II perspective
|
||||||
|
|
||||||
|
.define irq_write 4
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Implementation of the Apple II peripheral bus protocol:
|
||||||
|
|
||||||
|
- /DEVSEL, /IOSEL and /IOSTRB are supposed to combined to ENBL via an AND gate.
|
||||||
|
|
||||||
|
- On the falling edge of ENBL, the lines A0-A11 and R/W are sampled and pushed
|
||||||
|
into the 'enable' state machine RX FIFO.
|
||||||
|
|
||||||
|
- In case of an Apple II write cycle, the lines D0-D7 are sampled ~300ns later
|
||||||
|
and pushed into the 'write' state machine RX FIFO.
|
||||||
|
|
||||||
|
- If a byte is pushed into the 'read' state machine TX FIFO, it is driven out
|
||||||
|
to the lines D0-D7 until the rising edge of ENBL.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
.program enbl
|
||||||
|
|
||||||
|
.wrap_target
|
||||||
|
|
||||||
|
idle:
|
||||||
|
wait 1 gpio gpio_enbl // wait for ENBL to rise
|
||||||
|
wait 0 gpio gpio_enbl // wait for ENBL to fall
|
||||||
|
|
||||||
|
in pins, size_addr // shift A0-A11 + R/W into ISR
|
||||||
|
|
||||||
|
jmp pin idle // jump to idle if R/W is high
|
||||||
|
|
||||||
|
irq irq_write // Set 'write' IRQ
|
||||||
|
|
||||||
|
.wrap
|
||||||
|
|
||||||
|
% c-sdk {
|
||||||
|
static inline void enbl_program_init(uint offset) {
|
||||||
|
pio_sm_config c = enbl_program_get_default_config(offset);
|
||||||
|
|
||||||
|
// in_base: gpio_addr
|
||||||
|
sm_config_set_in_pins(&c, gpio_addr);
|
||||||
|
|
||||||
|
// shift_right: false
|
||||||
|
// autopush: true
|
||||||
|
// push_threshold: size_addr
|
||||||
|
sm_config_set_in_shift(&c, false, true, size_addr);
|
||||||
|
|
||||||
|
// pin: gpio_rw
|
||||||
|
sm_config_set_jmp_pin(&c, gpio_rw);
|
||||||
|
|
||||||
|
// state_machine: sm_enbl
|
||||||
|
// initial_pc: offset
|
||||||
|
pio_sm_init(pio0, sm_enbl, offset, &c);
|
||||||
|
|
||||||
|
// state_machine: sm_enbl
|
||||||
|
pio_sm_set_enabled(pio0, sm_enbl, true);
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
.program write
|
||||||
|
|
||||||
|
.wrap_target
|
||||||
|
|
||||||
|
wait 1 irq irq_write [31] // wait for 'write' IRQ to be set and clear it
|
||||||
|
// [31 cycles to allow 6502 to set up D0-D7]
|
||||||
|
|
||||||
|
in pins, size_data // shift D0-D7 into ISR
|
||||||
|
|
||||||
|
.wrap
|
||||||
|
|
||||||
|
% c-sdk {
|
||||||
|
static inline void write_program_init(uint offset) {
|
||||||
|
pio_sm_config c = write_program_get_default_config(offset);
|
||||||
|
|
||||||
|
// in_base: gpio_data
|
||||||
|
sm_config_set_in_pins(&c, gpio_data);
|
||||||
|
|
||||||
|
// shift_right: false
|
||||||
|
// autopush: true
|
||||||
|
// push_threshold: size_data
|
||||||
|
sm_config_set_in_shift(&c, false, true, size_data);
|
||||||
|
|
||||||
|
// state_machine: sm_write
|
||||||
|
// initial_pc: offset
|
||||||
|
pio_sm_init(pio0, sm_write, offset, &c);
|
||||||
|
|
||||||
|
// state_machine: sm_write
|
||||||
|
pio_sm_set_enabled(pio0, sm_write, true);
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
.program read
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Both set and set-side are limited to 5 pins each. So both set and side-set are
|
||||||
|
configured to set (the direction of) 4 pins. This approach allows to set the
|
||||||
|
direction of D0-D7 in one operation.
|
||||||
|
|
||||||
|
Note: The naive approach would have been
|
||||||
|
mov osr, ~x // move 0xFFFFFFFF to OSR
|
||||||
|
out pindirs, size_data // enable output of D0-D7
|
||||||
|
[...]
|
||||||
|
mov osr, x // move 0x00000000 to OSR
|
||||||
|
out pindirs, size_data // disable output of D0-D7
|
||||||
|
but this would have required two operations and destroyed OSR.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
.side_set (size_data / 2) opt pindirs
|
||||||
|
|
||||||
|
.wrap_target
|
||||||
|
|
||||||
|
pull block // pull data into OSR, block on empty FIFO
|
||||||
|
|
||||||
|
out pins, size_data // shift OSR out to D0-D7
|
||||||
|
|
||||||
|
set pindirs, 15 side 15 // enable output of D0-D7
|
||||||
|
|
||||||
|
wait 1 gpio gpio_enbl // wait for ENBL to rise
|
||||||
|
|
||||||
|
set pindirs, 0 side 0 // disable output of D0-D7
|
||||||
|
|
||||||
|
.wrap
|
||||||
|
|
||||||
|
% c-sdk {
|
||||||
|
static inline void read_program_init(uint offset) {
|
||||||
|
pio_sm_config c = read_program_get_default_config(offset);
|
||||||
|
|
||||||
|
// out_base: gpio_data
|
||||||
|
// out_count: size_data
|
||||||
|
sm_config_set_out_pins(&c, gpio_data, size_data);
|
||||||
|
|
||||||
|
// shift_right: true
|
||||||
|
// autopull: false
|
||||||
|
// pull_threshold: size_data
|
||||||
|
sm_config_set_out_shift(&c, true, false, size_data);
|
||||||
|
|
||||||
|
// set_base: gpio_data
|
||||||
|
// set_count: size_data / 2
|
||||||
|
sm_config_set_set_pins(&c, gpio_data, size_data / 2);
|
||||||
|
|
||||||
|
// sideset_base: gpio_data + size_data / 2
|
||||||
|
sm_config_set_sideset_pins(&c, gpio_data + size_data / 2);
|
||||||
|
|
||||||
|
// state_machine: sm_read
|
||||||
|
// initial_pc: offset
|
||||||
|
pio_sm_init(pio0, sm_read, offset, &c);
|
||||||
|
|
||||||
|
// state_machine: sm_read
|
||||||
|
pio_sm_set_enabled(pio0, sm_read, true);
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
6
pipico/incbin.S
Normal file
6
pipico/incbin.S
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.section .time_critical.firmware
|
||||||
|
.global firmware
|
||||||
|
.type firmware, %object
|
||||||
|
.balign 4
|
||||||
|
firmware:
|
||||||
|
.incbin "../../pidrive/PIROM#062000"
|
117
pipico/main.c
Normal file
117
pipico/main.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Oliver Schmidt (https://a2retro.de/)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "pico/printf.h"
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/multicore.h"
|
||||||
|
|
||||||
|
#include "bus.pio.h"
|
||||||
|
|
||||||
|
void board();
|
||||||
|
|
||||||
|
#ifdef TRACE
|
||||||
|
void uart_printf(uart_inst_t *uart, const char *format, ...) {
|
||||||
|
static char buffer[0x100];
|
||||||
|
|
||||||
|
va_list va;
|
||||||
|
va_start(va, format);
|
||||||
|
vsnprintf(buffer, sizeof(buffer), format, va);
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
buffer[0xFF] = '\0';
|
||||||
|
uart_puts(uart, buffer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
stdio_set_translate_crlf(&stdio_usb, false);
|
||||||
|
|
||||||
|
#ifdef TRACE
|
||||||
|
uart_init(uart0, 115200);
|
||||||
|
uart_set_translate_crlf(uart0, true);
|
||||||
|
gpio_set_function(0, GPIO_FUNC_UART);
|
||||||
|
gpio_set_function(1, GPIO_FUNC_UART);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (uint gpio = gpio_addr; gpio < gpio_addr + size_addr; gpio++) {
|
||||||
|
gpio_init(gpio);
|
||||||
|
gpio_set_pulls(gpio, false, false); // floating
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint gpio = gpio_data; gpio < gpio_data + size_data; gpio++) {
|
||||||
|
pio_gpio_init(pio0, gpio);
|
||||||
|
gpio_set_pulls(gpio, false, false); // floating
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_init(gpio_enbl);
|
||||||
|
gpio_set_pulls(gpio_enbl, false, false); // floating
|
||||||
|
|
||||||
|
gpio_init(gpio_irq);
|
||||||
|
gpio_pull_up(gpio_irq);
|
||||||
|
|
||||||
|
gpio_init(gpio_rdy);
|
||||||
|
gpio_pull_up(gpio_rdy);
|
||||||
|
|
||||||
|
gpio_init(gpio_led);
|
||||||
|
gpio_set_dir(gpio_led, GPIO_OUT);
|
||||||
|
|
||||||
|
uint offset;
|
||||||
|
|
||||||
|
offset = pio_add_program(pio0, &enbl_program);
|
||||||
|
enbl_program_init(offset);
|
||||||
|
|
||||||
|
offset = pio_add_program(pio0, &write_program);
|
||||||
|
write_program_init(offset);
|
||||||
|
|
||||||
|
offset = pio_add_program(pio0, &read_program);
|
||||||
|
read_program_init(offset);
|
||||||
|
|
||||||
|
multicore_launch_core1(board);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (multicore_fifo_rvalid()) {
|
||||||
|
uint32_t data = multicore_fifo_pop_blocking();
|
||||||
|
putchar(data);
|
||||||
|
#ifdef TRACE
|
||||||
|
uart_printf(uart0, "> %02X\n", data);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multicore_fifo_wready()) {
|
||||||
|
int data = getchar_timeout_us(0);
|
||||||
|
if (data != PICO_ERROR_TIMEOUT) {
|
||||||
|
multicore_fifo_push_blocking(data);
|
||||||
|
#ifdef TRACE
|
||||||
|
uart_printf(uart0, "< %02X\n", data);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
73
pipico/pico_sdk_import.cmake
Normal file
73
pipico/pico_sdk_import.cmake
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
|
||||||
|
|
||||||
|
# This can be dropped into an external project to help locate this SDK
|
||||||
|
# It should be include()ed prior to project()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
|
||||||
|
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
|
||||||
|
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
|
||||||
|
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
|
||||||
|
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
|
||||||
|
|
||||||
|
if (NOT PICO_SDK_PATH)
|
||||||
|
if (PICO_SDK_FETCH_FROM_GIT)
|
||||||
|
include(FetchContent)
|
||||||
|
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
|
||||||
|
if (PICO_SDK_FETCH_FROM_GIT_PATH)
|
||||||
|
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||||
|
endif ()
|
||||||
|
# GIT_SUBMODULES_RECURSE was added in 3.17
|
||||||
|
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
|
||||||
|
FetchContent_Declare(
|
||||||
|
pico_sdk
|
||||||
|
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
|
||||||
|
GIT_TAG master
|
||||||
|
GIT_SUBMODULES_RECURSE FALSE
|
||||||
|
)
|
||||||
|
else ()
|
||||||
|
FetchContent_Declare(
|
||||||
|
pico_sdk
|
||||||
|
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
|
||||||
|
GIT_TAG master
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT pico_sdk)
|
||||||
|
message("Downloading Raspberry Pi Pico SDK")
|
||||||
|
FetchContent_Populate(pico_sdk)
|
||||||
|
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
|
||||||
|
endif ()
|
||||||
|
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
|
||||||
|
else ()
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||||
|
if (NOT EXISTS ${PICO_SDK_PATH})
|
||||||
|
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||||
|
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
|
||||||
|
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
|
||||||
|
|
||||||
|
include(${PICO_SDK_INIT_CMAKE_FILE})
|
Loading…
Reference in New Issue
Block a user