Skip to content
Merged
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
3 changes: 2 additions & 1 deletion .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,8 @@
"-fsingle-precision-constant"
],
"cStandard": "c11",
"intelliSenseMode": "gcc-arm"
"intelliSenseMode": "gcc-arm",
"compilerPath": "arm-none-eabi-gcc"
},
{
"name": "pbio/test",
Expand Down
1 change: 1 addition & 0 deletions bricks/_common/sources.mk
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ PBIO_SRC_C = $(addprefix lib/pbio/,\
drv/pwm/pwm_core.c \
drv/pwm/pwm_ev3.c \
drv/pwm/pwm_lp50xx_stm32.c \
drv/pwm/pwm_pico.c \
drv/pwm/pwm_stm32_tim.c \
drv/pwm/pwm_test.c \
drv/pwm/pwm_tlc5955_stm32.c \
Expand Down
2 changes: 2 additions & 0 deletions lib/pbio/drv/pwm/pwm_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "pwm_lp50xx_stm32.h"
#include "pwm_tlc5955_stm32.h"
#include "pwm_ev3.h"
#include "pwm_pico.h"
#include "pwm.h"


Expand All @@ -28,6 +29,7 @@ void pbdrv_pwm_init(void) {
pbdrv_pwm_stm32_tim_init(pbdrv_pwm_dev);
pbdrv_pwm_test_init(pbdrv_pwm_dev);
pbdrv_pwm_lp50xx_stm32_init(pbdrv_pwm_dev);
pbdrv_pwm_pico_init(pbdrv_pwm_dev);
pbdrv_pwm_tlc5955_stm32_init(pbdrv_pwm_dev);
pbdrv_pwm_tiam1808_init(pbdrv_pwm_dev);
}
Expand Down
65 changes: 65 additions & 0 deletions lib/pbio/drv/pwm/pwm_pico.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2026 The Pybricks Authors

#include <pbdrv/config.h>

#if PBDRV_CONFIG_PWM_PICO

#include <pbdrv/pwm.h>
#include <pbdrv/gpio.h>
#include <pbio/error.h>

#include "../drv/pwm/pwm.h"
#include "../drv/pwm/pwm_pico.h"
#include "../../drv/led/led_pwm.h"

#include "hardware/gpio.h"
#include "hardware/pwm.h"

static pbio_error_t pbdrv_pwm_pico_set_duty(pbdrv_pwm_dev_t *dev, uint32_t ch, uint32_t value) {
// Blue not available.
if (ch == PBDRV_LED_PWM_CHANNEL_INVALID) {
return PBIO_SUCCESS;
}

if (ch >= PBDRV_CONFIG_PWM_PICO_NUM_CHANNELS) {
return PBIO_ERROR_INVALID_ARG;
}

const pbdrv_pwm_pico_platform_data_t *pdata = dev->pdata;
const pbdrv_pwm_pico_channel_t *channel = &pdata->channels[ch];

pwm_set_gpio_level(channel->gpio, value);

return PBIO_SUCCESS;
}

static const pbdrv_pwm_driver_funcs_t pbdrv_pwm_pico_funcs = {
.set_duty = pbdrv_pwm_pico_set_duty,
};

void pbdrv_pwm_pico_init(pbdrv_pwm_dev_t *devs) {
const pbdrv_pwm_pico_platform_data_t *pdata = &pbdrv_pwm_pico_platform_data;

devs[pdata->id].funcs = &pbdrv_pwm_pico_funcs;
devs[pdata->id].pdata = pdata;

for (int i = 0; i < PBDRV_CONFIG_PWM_PICO_NUM_CHANNELS; i++) {
const pbdrv_pwm_pico_channel_t *channel = &pdata->channels[i];

// Tell the LED pin that the PWM is in charge of its value.
gpio_set_function(channel->gpio, GPIO_FUNC_PWM);
// Figure out which slice we just connected to the LED pin
uint slice_num = pwm_gpio_to_slice_num(channel->gpio);

// Get some sensible defaults for the slice configuration. By default,
// the counter is allowed to wrap over its maximum range (0 to 2**16-1).
pwm_config config = pwm_get_default_config();
// Set divider, reduces counter clock to sysclock/this value.
pwm_config_set_clkdiv(&config, 4.f);
// Load the configuration into our PWM slice, and set it running.
pwm_init(slice_num, &config, true);
}
}

#endif // PBDRV_CONFIG_PWM_PICO
39 changes: 39 additions & 0 deletions lib/pbio/drv/pwm/pwm_pico.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2026 The Pybricks Authors

// Hooks for unit picos.

#ifndef _INTERNAL_PBDRV_PWM_PICO_H_
#define _INTERNAL_PBDRV_PWM_PICO_H_

#include <pbdrv/config.h>

#if PBDRV_CONFIG_PWM_PICO

#include <stdint.h>

#include <pbdrv/pwm.h>

/** Platform-specific device information. */

typedef struct {
uint8_t gpio;
} pbdrv_pwm_pico_channel_t;

typedef struct {
uint8_t id;
pbdrv_pwm_pico_channel_t channels[PBDRV_CONFIG_PWM_PICO_NUM_CHANNELS];
} pbdrv_pwm_pico_platform_data_t;

// Defined in platform.c
extern const pbdrv_pwm_pico_platform_data_t pbdrv_pwm_pico_platform_data;

void pbdrv_pwm_pico_init(pbdrv_pwm_dev_t *devs);

#else // PBDRV_CONFIG_PWM_PICO

#define pbdrv_pwm_pico_init(dev)

#endif // PBDRV_CONFIG_PWM_PICO

#endif // _INTERNAL_PBDRV_PWM_PICO_H_
12 changes: 8 additions & 4 deletions lib/pbio/platform/build_hat/pbdrvconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,18 @@
#define PBDRV_CONFIG_IOPORT_HAS_UART (1)
// TODO: Implement IOPORT driver for Build HAT

#define PBDRV_CONFIG_LED (0)
// TODO: Implement LED driver for Build HAT (should be similar to EV3)
#define PBDRV_CONFIG_LED (1)
#define PBDRV_CONFIG_LED_NUM_DEV (1)
#define PBDRV_CONFIG_LED_PWM (1)
#define PBDRV_CONFIG_LED_PWM_NUM_DEV (1)

#define PBDRV_CONFIG_MOTOR_DRIVER (0)
// TODO: Implement motor driver for Build HAT

#define PBDRV_CONFIG_PWM (0)
// TODO: Implement PWM driver for Build HAT
#define PBDRV_CONFIG_PWM (1)
#define PBDRV_CONFIG_PWM_NUM_DEV (1)
#define PBDRV_CONFIG_PWM_PICO (1)
#define PBDRV_CONFIG_PWM_PICO_NUM_CHANNELS (2)

#define PBDRV_CONFIG_RANDOM (0)
// TODO: Implement RANDOM driver for Build HAT
Expand Down
2 changes: 1 addition & 1 deletion lib/pbio/platform/build_hat/pbioconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#define PBIO_CONFIG_DCMOTOR_NUM_DEV (4)
#define PBIO_CONFIG_DRIVEBASE_SPIKE (0)
#define PBIO_CONFIG_IMU (0) // TODO
#define PBIO_CONFIG_LIGHT (0) // TODO
#define PBIO_CONFIG_LIGHT (1)
#define PBIO_CONFIG_LOGGER (1)
#define PBIO_CONFIG_MOTOR_PROCESS (1)
#define PBIO_CONFIG_PORT (0) // TODO
Expand Down
2 changes: 1 addition & 1 deletion lib/pbio/platform/build_hat/pbsysconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#define PBSYS_CONFIG_STORAGE (0) // TODO ?
#define PBSYS_CONFIG_STORAGE_NUM_SLOTS (1)
#define PBSYS_CONFIG_STORAGE_USER_DATA_SIZE (128)
#define PBSYS_CONFIG_STATUS_LIGHT (0) // TODO
#define PBSYS_CONFIG_STATUS_LIGHT (1)
#define PBSYS_CONFIG_STATUS_LIGHT_BATTERY (0)
#define PBSYS_CONFIG_STATUS_LIGHT_BLUETOOTH (0)
#define PBSYS_CONFIG_STATUS_LIGHT_STATE_ANIMATIONS (1)
Expand Down
51 changes: 50 additions & 1 deletion lib/pbio/platform/build_hat/platform.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,63 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2025 The Pybricks Authors
// Copyright (c) 2025-2026 The Pybricks Authors

#include <pbdrv/gpio.h>

#include "../../drv/led/led_pwm.h"
#include "../../drv/pwm/pwm_pico.h"

#include "hardware/gpio.h"

enum {
PWM_DEV_0,
};

enum {
LED_DEV_0_STATUS,
};

const pbdrv_gpio_t pbdrv_ioport_platform_data_vcc_pin = {
.pin = 17,
};

// LED

static const pbdrv_led_pwm_platform_color_t pbdrv_led_pwm_color = {
.r_factor = 1000,
.g_factor = 1000,
.b_factor = 0,
// Tuned with scale_factor=17 so pure red/green are as close as possible
// to UINT16_MAX without exceeding it.
.r_brightness = 83,
.g_brightness = 83,
.b_brightness = 0,
};

const pbdrv_led_pwm_platform_data_t pbdrv_led_pwm_platform_data[PBDRV_CONFIG_LED_PWM_NUM_DEV] = {
{
.color = &pbdrv_led_pwm_color,
.id = LED_DEV_0_STATUS,
.r_id = PWM_DEV_0,
.r_ch = 0,
.g_id = PWM_DEV_0,
.g_ch = 1,
// Blue not available.
.b_id = PWM_DEV_0,
.b_ch = PBDRV_LED_PWM_CHANNEL_INVALID,
.scale_factor = 17,
},
};

// PWM

const pbdrv_pwm_pico_platform_data_t pbdrv_pwm_pico_platform_data = {
.id = PWM_DEV_0,
.channels = {
{ .gpio = 14 }, // LED0
{ .gpio = 15 }, // LED1
}
};

int main(void) {
extern void pbsys_main(void);
pbsys_main();
Expand Down
7 changes: 6 additions & 1 deletion pybricks/hubs/pb_type_buildhat.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2025 The Pybricks Authors
// Copyright (c) 2025-2026 The Pybricks Authors

#include "py/mpconfig.h"

#if PYBRICKS_PY_HUBS && PYBRICKS_HUB_BUILDHAT

#include <pbsys/light.h>

#include <pybricks/common.h>
#include <pybricks/hubs.h>

Expand All @@ -13,16 +15,19 @@

typedef struct _hubs_BuildHat_obj_t {
mp_obj_base_t base;
mp_obj_t light;
mp_obj_t system;
} hubs_BuildHat_obj_t;

static mp_obj_t hubs_BuildHat_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
hubs_BuildHat_obj_t *self = mp_obj_malloc(hubs_BuildHat_obj_t, type);
self->light = common_ColorLight_internal_obj_new(pbsys_status_light_main);
self->system = MP_OBJ_FROM_PTR(&pb_type_System);
return MP_OBJ_FROM_PTR(self);
}

static const pb_attr_dict_entry_t hubs_BuildHat_attr_dict[] = {
PB_DEFINE_CONST_ATTR_RO(MP_QSTR_light, hubs_BuildHat_obj_t, light),
PB_DEFINE_CONST_ATTR_RO(MP_QSTR_system, hubs_BuildHat_obj_t, system),
PB_ATTR_DICT_SENTINEL
};
Expand Down
Loading