Skip to content

Commit 9549e1e

Browse files
committed
Finalize alpha Swift support
Signed-off-by: paulober <[email protected]>
1 parent 04c16e9 commit 9549e1e

File tree

6 files changed

+104
-11
lines changed

6 files changed

+104
-11
lines changed

README.md

+41
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ For comprehensive setup instructions, refer to the [Getting Started guide](https
1313
### Project Setup and Management
1414

1515
- **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.
16+
- **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.
1617
- **Quick Project Setup**: Initiate new Pico projects directly from the Explorer view, when no workspace is open.
1718
- **MicroPython Support**: Create and develop MicroPython-based Pico projects with support provided through the [MicroPico](https://github.com/paulober/MicroPico) extension.
1819

@@ -87,6 +88,46 @@ For optimal functionality, consider enabling:
8788

8889
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.
8990

91+
## Swift Support
92+
93+
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:
94+
95+
### 1. Install the Swift Experimental Toolchain
96+
97+
Download and install the latest Swift experimental toolchain for your platform:
98+
99+
- **Linux**: [Install Swift for Linux](https://www.swift.org/install/linux/#platforms)
100+
- **macOS**: [Install Swift for macOS](https://www.swift.org/install/macos)
101+
102+
> **Note:** Windows is not currently supported.
103+
104+
### 2. Configure the Swift Toolchain
105+
106+
#### **For Linux:**
107+
Ensure the `swiftc` executable is included in your system's `PATH`. Once added, restart VS Code for the changes to take effect.
108+
109+
#### **For macOS:**
110+
If the build fails or the Swift toolchain isn’t detected, force the toolchain selection by adding the following line to your `~/.zprofile`:
111+
112+
- **For system-wide installation:**
113+
```zsh
114+
export TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw /Library/Developer/Toolchains/swift-latest.xctoolchain/Info.plist)
115+
```
116+
117+
- **For user-specific installation:**
118+
```zsh
119+
export TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw $HOME/Library/Developer/Toolchains/swift-latest.xctoolchain/Info.plist)
120+
```
121+
122+
Then, restart your terminal and reopen VS Code.
123+
124+
### 3. Create a New Pico Project with Swift
125+
126+
1. Open VS Code.
127+
2. Use the **"Generate Swift Code"** option to create a new Pico project with Swift support enabled.
128+
> Note: At the moment, Swift support is only available for new projects based on Pico 2 and Pico SDK v2.1.0.
129+
3. Start building your Swift-powered Pico project!
130+
90131
## VS Code Profiles
91132

92133
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:

scripts/bridge.h

+14
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44
#define PICO_DEFAULT_LED_PIN 6
55
#endif
66

7+
#ifdef _HARDWARE_STRUCTS_INTERP_H
8+
#ifdef interp0
9+
interp_hw_t* get_interp0(void) {
10+
return interp0;
11+
}
12+
#endif
13+
14+
#ifdef interp1
15+
interp_hw_t* get_interp1(void) {
16+
return interp1;
17+
}
18+
#endif
19+
#endif
20+
721
#ifdef _HARDWARE_STRUCTS_SPI_H
822
#ifdef spi0
923
spi_inst_t* get_spi0(void) {

scripts/pico_project.py

+12-9
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,8 @@ def GDB_NAME():
559559
"// GPIO initialisation.",
560560
"// We will make this GPIO an input, and pull it up by default",
561561
"gpio_init(GPIO)",
562-
"gpio_set_dir(GPIO, GPIO_IN)",
562+
# "gpio_set_dir(GPIO, GPIO_IN)",
563+
"PicoGPIO.setDirection(pin: GPIO, direction: .input)",
563564
"gpio_pull_up(GPIO)",
564565
"// See https://github.com/raspberrypi/pico-examples/tree/master/gpio for other gpio examples, including using interrupts",
565566
),
@@ -568,18 +569,18 @@ def GDB_NAME():
568569
(),
569570
(
570571
"// Interpolator example code",
571-
"interp_config cfg = interp_default_config()",
572+
"var cfg = interp_default_config()",
572573
"// Now use the various interpolator library functions for your use case",
573574
"// e.g. interp_config_clamp(&cfg, true)",
574575
"// interp_config_shift(&cfg, 2)",
575576
"// Then set the config ",
576-
"interp_set_config(interp0, 0, &cfg)",
577+
"interp_set_config(get_interp0(), 0, &cfg)",
577578
"// For examples of interpolator use see https://github.com/raspberrypi/pico-examples/tree/master/interp",
578579
),
579580
],
580581
"timer": [
581582
(
582-
"func alarm_callback(id: alarm_id_t, user_data: void): int64_t {",
583+
"func alarm_callback(id: alarm_id_t, user_data: UnsafeMutableRawPointer?) -> Int64 {",
583584
" // Put your timeout handler code in here",
584585
" return 0",
585586
"}",
@@ -595,13 +596,13 @@ def GDB_NAME():
595596
(
596597
"// Watchdog example code",
597598
"if watchdog_caused_reboot() {",
598-
' printf("Rebooted by Watchdog!\\n")',
599+
' print("Rebooted by Watchdog!")',
599600
" // Whatever action you may take if a watchdog caused a reboot",
600601
"}",
601602
"",
602603
"// Enable the watchdog, requiring the watchdog to be updated every 100ms or the chip will reboot",
603604
"// second arg is pause on debug which means the watchdog will pause when stepping through code",
604-
"watchdog_enable(100, 1)",
605+
"watchdog_enable(100, true)",
605606
"",
606607
"// You need to call this function at least more often than the 100ms in the enable call to prevent a reboot",
607608
"watchdog_update()",
@@ -1182,11 +1183,10 @@ def GenerateCMake(folder, params):
11821183
if params["useSwift"]:
11831184
cmake_if_apple = (
11841185
"if(APPLE)\n"
1185-
" execute_process(COMMAND xcrun -f swiftc OUTPUT_VARIABLE SWIFTC OUTPUT_STRIP_TRAILING_WHITESPACE)\n"
1186+
" execute_process(COMMAND xcrun --toolchain swift -f swiftc OUTPUT_VARIABLE SWIFTC OUTPUT_STRIP_TRAILING_WHITESPACE)\n"
11861187
" execute_process(COMMAND dirname ${SWIFTC} OUTPUT_VARIABLE SWIFTC_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)\n"
11871188
"elseif(WIN32)\n"
1188-
" execute_process(COMMAND where.exe swiftc OUTPUT_VARIABLE SWIFTC OUTPUT_STRIP_TRAILING_WHITESPACE)\n"
1189-
' string(REGEX REPLACE "(.*)\\\\\\\\[^\\\\\\\\]*$" "\\\\1" SWIFTC_DIR "${SWIFTC}")\n'
1189+
' message(FATAL_ERROR "Embedded Swift is currently not supported on Windows")\n'
11901190
"else()\n"
11911191
" execute_process(COMMAND which swiftc OUTPUT_VARIABLE SWIFTC OUTPUT_STRIP_TRAILING_WHITESPACE)\n"
11921192
" execute_process(COMMAND dirname ${SWIFTC} OUTPUT_VARIABLE SWIFTC_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)\n"
@@ -1938,6 +1938,9 @@ def DoEverything(params):
19381938
if args.debugger > len(debugger_list) - 1:
19391939
args.debugger = 0
19401940

1941+
if args.swift and args.cpp:
1942+
args.swift = False
1943+
19411944
if "RISCV" in args.toolchainVersion:
19421945
if "COREV" in args.toolchainVersion:
19431946
COMPILER_TRIPLE = COREV_TRIPLE

src/commands/newProject.mts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default class NewProjectCommand extends CommandWithArgs {
1919
private readonly _logger: Logger = new Logger("NewProjectCommand");
2020
private readonly _extensionUri: Uri;
2121
private static readonly micropythonOption = "MicroPython";
22-
private static readonly cCppOption = "C/C++";
22+
private static readonly cCppOption = "C/C++/Swift";
2323

2424
public static readonly id = "newProject";
2525

src/webview/newProjectPanel.mts

+6-1
Original file line numberDiff line numberDiff line change
@@ -2123,12 +2123,17 @@ export class NewProjectPanel {
21232123
<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>
21242124
</div>
21252125
</li>
2126+
${
2127+
!isWindows
2128+
? `
21262129
<li class="w-full border-b border-gray-200 sm:border-b-0 sm:border-r dark:border-gray-600">
21272130
<div class="flex items-center pl-3">
21282131
<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">
21292132
<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>
21302133
</div>
2131-
</li>
2134+
</li>`
2135+
: ""
2136+
}
21322137
<li class="w-full border-b border-gray-200 sm:border-b-0 sm:border-r dark:border-gray-600">
21332138
<div class="flex items-center pl-3">
21342139
<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">

web/main.js

+30
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,36 @@ var exampleSupportedBoards = [];
750750
});
751751
}
752752

753+
const swiftCodeGen = document.getElementById('swift-code-gen-cblist');
754+
if (swiftCodeGen) {
755+
swiftCodeGen.addEventListener('change', function (event) {
756+
const checked = event.currentTarget.checked;
757+
if (!checked) {
758+
return;
759+
}
760+
761+
const cppCodeGen = document.getElementById('cpp-code-gen-cblist');
762+
if (cppCodeGen) {
763+
cppCodeGen.checked = false;
764+
}
765+
});
766+
}
767+
768+
const cppCodeGen = document.getElementById('cpp-code-gen-cblist');
769+
if (cppCodeGen) {
770+
cppCodeGen.addEventListener('change', function (event) {
771+
const checked = event.currentTarget.checked;
772+
if (!checked) {
773+
return;
774+
}
775+
776+
const swiftCodeGen = document.getElementById('swift-code-gen-cblist');
777+
if (swiftCodeGen) {
778+
swiftCodeGen.checked = false;
779+
}
780+
});
781+
}
782+
753783
const ninjaVersionRadio = document.getElementsByName('ninja-version-radio');
754784
if (ninjaVersionRadio.length > 0)
755785
ninjaVersionRadio[0].checked = true;

0 commit comments

Comments
 (0)