Skip to content

Commit

Permalink
Finalize alpha Swift support
Browse files Browse the repository at this point in the history
Signed-off-by: paulober <[email protected]>
  • Loading branch information
paulober committed Dec 5, 2024
1 parent 04c16e9 commit 9549e1e
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 11 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ For comprehensive setup instructions, refer to the [Getting Started guide](https
### Project Setup and Management

- **Project Generator**: Easily create and configure new projects with support for advanced Pico features like I2C and PIO. The generator targets the Ninja build system and allows customization during project creation.
- **Swift Language Support**: Develop Pico projects using the Swift programming language by leveraging the latest **experimental** Swift toolchain. Generate Swift-enabled projects directly from the extension.
- **Quick Project Setup**: Initiate new Pico projects directly from the Explorer view, when no workspace is open.
- **MicroPython Support**: Create and develop MicroPython-based Pico projects with support provided through the [MicroPico](https://github.com/paulober/MicroPico) extension.

Expand Down Expand Up @@ -87,6 +88,46 @@ For optimal functionality, consider enabling:

When prompted, select the `Pico` kit in CMake Tools, and set your build and launch targets accordingly. Use CMake Tools for compilation, but continue using this extension for debugging, as CMake Tools debugging is not compatible with Pico.

## Swift Support

The Pico VS Code extension supports Swift, enabling you to develop Raspberry Pi Pico projects using the Swift programming language. To enable Swift support, follow these steps:

### 1. Install the Swift Experimental Toolchain

Download and install the latest Swift experimental toolchain for your platform:

- **Linux**: [Install Swift for Linux](https://www.swift.org/install/linux/#platforms)
- **macOS**: [Install Swift for macOS](https://www.swift.org/install/macos)

> **Note:** Windows is not currently supported.
### 2. Configure the Swift Toolchain

#### **For Linux:**
Ensure the `swiftc` executable is included in your system's `PATH`. Once added, restart VS Code for the changes to take effect.

#### **For macOS:**
If the build fails or the Swift toolchain isn’t detected, force the toolchain selection by adding the following line to your `~/.zprofile`:

- **For system-wide installation:**
```zsh
export TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw /Library/Developer/Toolchains/swift-latest.xctoolchain/Info.plist)
```

- **For user-specific installation:**
```zsh
export TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw $HOME/Library/Developer/Toolchains/swift-latest.xctoolchain/Info.plist)
```

Then, restart your terminal and reopen VS Code.

### 3. Create a New Pico Project with Swift

1. Open VS Code.
2. Use the **"Generate Swift Code"** option to create a new Pico project with Swift support enabled.
> Note: At the moment, Swift support is only available for new projects based on Pico 2 and Pico SDK v2.1.0.
3. Start building your Swift-powered Pico project!

## VS Code Profiles

If you work with multiple microcontroller toolchains, consider installing this extension into a [VS Code Profile](https://code.visualstudio.com/docs/editor/profiles) to avoid conflicts with other toolchains. Follow these steps:
Expand Down
14 changes: 14 additions & 0 deletions scripts/bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@
#define PICO_DEFAULT_LED_PIN 6
#endif

#ifdef _HARDWARE_STRUCTS_INTERP_H
#ifdef interp0
interp_hw_t* get_interp0(void) {
return interp0;
}
#endif

#ifdef interp1
interp_hw_t* get_interp1(void) {
return interp1;
}
#endif
#endif

#ifdef _HARDWARE_STRUCTS_SPI_H
#ifdef spi0
spi_inst_t* get_spi0(void) {
Expand Down
21 changes: 12 additions & 9 deletions scripts/pico_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,8 @@ def GDB_NAME():
"// GPIO initialisation.",
"// We will make this GPIO an input, and pull it up by default",
"gpio_init(GPIO)",
"gpio_set_dir(GPIO, GPIO_IN)",
# "gpio_set_dir(GPIO, GPIO_IN)",
"PicoGPIO.setDirection(pin: GPIO, direction: .input)",
"gpio_pull_up(GPIO)",
"// See https://github.com/raspberrypi/pico-examples/tree/master/gpio for other gpio examples, including using interrupts",
),
Expand All @@ -568,18 +569,18 @@ def GDB_NAME():
(),
(
"// Interpolator example code",
"interp_config cfg = interp_default_config()",
"var cfg = interp_default_config()",
"// Now use the various interpolator library functions for your use case",
"// e.g. interp_config_clamp(&cfg, true)",
"// interp_config_shift(&cfg, 2)",
"// Then set the config ",
"interp_set_config(interp0, 0, &cfg)",
"interp_set_config(get_interp0(), 0, &cfg)",
"// For examples of interpolator use see https://github.com/raspberrypi/pico-examples/tree/master/interp",
),
],
"timer": [
(
"func alarm_callback(id: alarm_id_t, user_data: void): int64_t {",
"func alarm_callback(id: alarm_id_t, user_data: UnsafeMutableRawPointer?) -> Int64 {",
" // Put your timeout handler code in here",
" return 0",
"}",
Expand All @@ -595,13 +596,13 @@ def GDB_NAME():
(
"// Watchdog example code",
"if watchdog_caused_reboot() {",
' printf("Rebooted by Watchdog!\\n")',
' print("Rebooted by Watchdog!")',
" // Whatever action you may take if a watchdog caused a reboot",
"}",
"",
"// Enable the watchdog, requiring the watchdog to be updated every 100ms or the chip will reboot",
"// second arg is pause on debug which means the watchdog will pause when stepping through code",
"watchdog_enable(100, 1)",
"watchdog_enable(100, true)",
"",
"// You need to call this function at least more often than the 100ms in the enable call to prevent a reboot",
"watchdog_update()",
Expand Down Expand Up @@ -1182,11 +1183,10 @@ def GenerateCMake(folder, params):
if params["useSwift"]:
cmake_if_apple = (
"if(APPLE)\n"
" execute_process(COMMAND xcrun -f swiftc OUTPUT_VARIABLE SWIFTC OUTPUT_STRIP_TRAILING_WHITESPACE)\n"
" execute_process(COMMAND xcrun --toolchain swift -f swiftc OUTPUT_VARIABLE SWIFTC OUTPUT_STRIP_TRAILING_WHITESPACE)\n"
" execute_process(COMMAND dirname ${SWIFTC} OUTPUT_VARIABLE SWIFTC_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)\n"
"elseif(WIN32)\n"
" execute_process(COMMAND where.exe swiftc OUTPUT_VARIABLE SWIFTC OUTPUT_STRIP_TRAILING_WHITESPACE)\n"
' string(REGEX REPLACE "(.*)\\\\\\\\[^\\\\\\\\]*$" "\\\\1" SWIFTC_DIR "${SWIFTC}")\n'
' message(FATAL_ERROR "Embedded Swift is currently not supported on Windows")\n'
"else()\n"
" execute_process(COMMAND which swiftc OUTPUT_VARIABLE SWIFTC OUTPUT_STRIP_TRAILING_WHITESPACE)\n"
" execute_process(COMMAND dirname ${SWIFTC} OUTPUT_VARIABLE SWIFTC_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)\n"
Expand Down Expand Up @@ -1938,6 +1938,9 @@ def DoEverything(params):
if args.debugger > len(debugger_list) - 1:
args.debugger = 0

if args.swift and args.cpp:
args.swift = False

if "RISCV" in args.toolchainVersion:
if "COREV" in args.toolchainVersion:
COMPILER_TRIPLE = COREV_TRIPLE
Expand Down
2 changes: 1 addition & 1 deletion src/commands/newProject.mts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default class NewProjectCommand extends CommandWithArgs {
private readonly _logger: Logger = new Logger("NewProjectCommand");
private readonly _extensionUri: Uri;
private static readonly micropythonOption = "MicroPython";
private static readonly cCppOption = "C/C++";
private static readonly cCppOption = "C/C++/Swift";

public static readonly id = "newProject";

Expand Down
7 changes: 6 additions & 1 deletion src/webview/newProjectPanel.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2123,12 +2123,17 @@ export class NewProjectPanel {
<label for="cpp-code-gen-cblist" class="w-full py-3 ml-2 text-sm font-medium text-gray-900 dark:text-gray-300">Generate C++ code</label>
</div>
</li>
${
!isWindows
? `
<li class="w-full border-b border-gray-200 sm:border-b-0 sm:border-r dark:border-gray-600">
<div class="flex items-center pl-3">
<input id="swift-code-gen-cblist" type="checkbox" value="" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-700 dark:focus:ring-offset-gray-700 focus:ring-2 dark:bg-gray-600 dark:border-gray-500">
<label for="swift-code-gen-cblist" class="w-full py-3 ml-2 text-sm font-medium text-gray-900 dark:text-gray-300">Generate Swift code</label>
</div>
</li>
</li>`
: ""
}
<li class="w-full border-b border-gray-200 sm:border-b-0 sm:border-r dark:border-gray-600">
<div class="flex items-center pl-3">
<input id="cpp-rtti-code-gen-cblist" type="checkbox" value="" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-700 dark:focus:ring-offset-gray-700 focus:ring-2 dark:bg-gray-600 dark:border-gray-500">
Expand Down
30 changes: 30 additions & 0 deletions web/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,36 @@ var exampleSupportedBoards = [];
});
}

const swiftCodeGen = document.getElementById('swift-code-gen-cblist');
if (swiftCodeGen) {
swiftCodeGen.addEventListener('change', function (event) {
const checked = event.currentTarget.checked;
if (!checked) {
return;
}

const cppCodeGen = document.getElementById('cpp-code-gen-cblist');
if (cppCodeGen) {
cppCodeGen.checked = false;
}
});
}

const cppCodeGen = document.getElementById('cpp-code-gen-cblist');
if (cppCodeGen) {
cppCodeGen.addEventListener('change', function (event) {
const checked = event.currentTarget.checked;
if (!checked) {
return;
}

const swiftCodeGen = document.getElementById('swift-code-gen-cblist');
if (swiftCodeGen) {
swiftCodeGen.checked = false;
}
});
}

const ninjaVersionRadio = document.getElementsByName('ninja-version-radio');
if (ninjaVersionRadio.length > 0)
ninjaVersionRadio[0].checked = true;
Expand Down

0 comments on commit 9549e1e

Please sign in to comment.