Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift support #132

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
17 changes: 17 additions & 0 deletions scripts/PicoSDK.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// This file contains a swift wrapper for some Pico SDK C style stuff
// Upercase library names can be used to only include helpers for available APIs

#if PICO_STDLIB
public struct PicoGPIO {
/// Enum for GPIO direction, mirroring the C enum
public enum Direction: UInt8 {
case input = 0
case output = 1
}

/// Swift-friendly wrapper for gpio_set_dir
public static func setDirection(pin: UInt32, direction: Direction) {
gpio_set_dir(pin, direction.rawValue != 0)
}
}
#endif
38 changes: 38 additions & 0 deletions scripts/bridge.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <errno.h>
#include <malloc.h>

/**
* @brief Allocates aligned memory in accordance with POSIX standards.
*
* The `posix_memalign` function allocates a block of memory with the specified alignment
* and size. The allocated memory is stored in the location pointed to by `memptr`. The
* alignment must be a power of two and a multiple of `sizeof(void *)`. This function is
* typically used for ensuring memory alignment for hardware or performance requirements.
*
* @param[out] memptr A pointer to the memory location where the aligned memory will be stored.
* This parameter must not be NULL.
* @param[in] alignment The alignment boundary in bytes. Must be a power of two and a multiple
* of `sizeof(void *)`.
* @param[in] size The size of the memory block to allocate in bytes.
*
* @return int Returns 0 on success. On failure, returns:
* - `EINVAL` if the alignment is invalid (not a power of two or not a multiple of `sizeof(void *)`).
* - `ENOMEM` if memory allocation fails.
*
* @note The caller is responsible for freeing the allocated memory using `free()` when it is no longer needed.
*/
int posix_memalign(void **memptr, size_t alignment, size_t size) {
// Validate alignment requirements
if ((alignment % sizeof(void *) != 0) || (alignment & (alignment - 1)) != 0) {
return EINVAL; // Invalid alignment
}

// Use memalign to allocate memory
void *ptr = memalign(alignment, size);
if (ptr == NULL) {
return ENOMEM; // Memory allocation failure
}

*memptr = ptr; // Set the memory pointer
return 0; // Success
}
108 changes: 108 additions & 0 deletions scripts/bridge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#pragma once

#ifndef PICO_DEFAULT_LED_PIN
#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) {
return spi0;
}
#endif

#ifdef spi1
spi_inst_t* get_spi1(void) {
return spi1;
}
#endif
#endif

#ifdef _HARDWARE_STRUCTS_I2C_H
#ifdef i2c0
i2c_inst_t* get_i2c0(void) {
return i2c0;
}
#endif

#ifdef i2c1
i2c_inst_t* get_i2c1(void) {
return i2c1;
}
#endif
#endif

#ifdef _HARDWARE_STRUCTS_PIO_H
#ifdef pio0
pio_hw_t* get_pio0(void) {
return pio0;
}
#endif

#ifdef pio1
pio_hw_t* get_pio1(void) {
return pio1;
}
#endif

#ifdef pio2
pio_hw_t* get_pio2(void) {
return pio2;
}
#endif
#endif

/**
* @file bridge.h
* @brief Simplifies the usage of specific SDK features in Swift by providing wrapper functions.
*
* This header acts as a bridge between C and Swift, exposing certain features of the Pico SDK
* in a simplified manner. For example it includes helper functions for accessing predefined
* UART instances (`uart0` and `uart1`), making them easily callable from Swift.
*/

#ifdef _HARDWARE_STRUCTS_UART_H // Ensure that UART hardware structs are included before compiling

#ifdef uart0
/**
* @brief Retrieves the instance for UART0.
*
* This function provides access to the pre-defined `uart0` instance,
* allowing straightforward interaction with the UART hardware from Swift.
*
* @return Pointer to the `uart0` instance.
*/
uart_inst_t* get_uart0(void) {
return uart0;
}
#endif

#ifdef uart1
/**
* @brief Retrieves the instance for UART1.
*
* This function provides access to the pre-defined `uart1` instance,
* allowing straightforward interaction with the UART hardware from Swift.
*
* @return Pointer to the `uart1` instance.
*/
uart_inst_t* get_uart1(void) {
return uart1;
}
#endif

#endif
Loading
Loading