Skip to content

Enable protomatter on RP2040 builds #4186

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

Merged
merged 4 commits into from
Mar 3, 2021
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
2 changes: 1 addition & 1 deletion ports/atmel-samd/common-hal/rgbmatrix/RGBMatrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include "samd/timers.h"
#include "timer_handler.h"

void *common_hal_rgbmatrix_timer_allocate() {
void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self) {
uint8_t timer_index = find_free_timer();
if (timer_index == 0xff) {
return NULL;
Expand Down
4 changes: 3 additions & 1 deletion ports/atmel-samd/common-hal/rgbmatrix/RGBMatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H
#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H

void *common_hal_rgbmatrix_timer_allocate(void);
#include "shared-module/rgbmatrix/RGBMatrix.h"

void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self);
void common_hal_rgbmatrix_timer_enable(void*);
void common_hal_rgbmatrix_timer_disable(void*);
void common_hal_rgbmatrix_timer_free(void*);
Expand Down
2 changes: 1 addition & 1 deletion ports/nrf/common-hal/rgbmatrix/RGBMatrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

extern void _PM_IRQ_HANDLER(void);

void *common_hal_rgbmatrix_timer_allocate() {
void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self) {
nrfx_timer_t *timer = nrf_peripherals_allocate_timer_or_throw();
nrf_peripherals_timer_never_reset(timer);
return timer->p_reg;
Expand Down
4 changes: 3 additions & 1 deletion ports/nrf/common-hal/rgbmatrix/RGBMatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_RGBMATRIX_RGBMATRIX_H
#define MICROPY_INCLUDED_NRF_COMMON_HAL_RGBMATRIX_RGBMATRIX_H

void *common_hal_rgbmatrix_timer_allocate(void);
#include "shared-module/rgbmatrix/RGBMatrix.h"

void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self);
void common_hal_rgbmatrix_timer_enable(void*);
void common_hal_rgbmatrix_timer_disable(void*);
void common_hal_rgbmatrix_timer_free(void*);
Expand Down
78 changes: 50 additions & 28 deletions ports/raspberrypi/common-hal/pwmio/PWMOut.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,22 @@ static uint32_t _mask(uint8_t slice, uint8_t channel) {
return 1 << (slice * CHANNELS_PER_SLICE + channel);
}

void pwmout_never_reset(uint8_t slice, uint8_t channel) {
never_reset_channel |= _mask(slice, channel);
}

void pwmout_reset_ok(uint8_t slice, uint8_t channel) {
never_reset_channel &= ~_mask(slice, channel);
}

void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) {
never_reset_channel |= _mask(self->slice, self->channel);
pwmout_never_reset(self->slice, self->channel);

never_reset_pin_number(self->pin->number);
}

void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) {
never_reset_channel &= ~_mask(self->slice, self->channel);
pwmout_reset_ok(self->slice, self->channel);
}

void pwmout_reset(void) {
Expand All @@ -92,21 +100,7 @@ void pwmout_reset(void) {
}
}

pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t* self,
const mcu_pin_obj_t* pin,
uint16_t duty,
uint32_t frequency,
bool variable_frequency) {
self->pin = pin;
self->variable_frequency = variable_frequency;
self->duty_cycle = duty;

if (frequency == 0 || frequency > (common_hal_mcu_processor_get_frequency() / 2)) {
return PWMOUT_INVALID_FREQUENCY;
}

uint8_t slice = pwm_gpio_to_slice_num(pin->number);
uint8_t channel = pwm_gpio_to_channel(pin->number);
pwmout_result_t pwmout_allocate(uint8_t slice, uint8_t channel, bool variable_frequency, uint32_t frequency) {
uint32_t channel_use_mask = _mask(slice, channel);

// Check the channel first.
Expand All @@ -128,14 +122,39 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t* self,
return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
}
}
self->slice = slice;
self->channel = channel;

channel_use |= channel_use_mask;
if (variable_frequency) {
slice_variable_frequency |= 1 << slice;
}

return PWMOUT_OK;
}

pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t* self,
const mcu_pin_obj_t* pin,
uint16_t duty,
uint32_t frequency,
bool variable_frequency) {
self->pin = pin;
self->variable_frequency = variable_frequency;
self->duty_cycle = duty;

if (frequency == 0 || frequency > (common_hal_mcu_processor_get_frequency() / 2)) {
return PWMOUT_INVALID_FREQUENCY;
}

uint8_t slice = pwm_gpio_to_slice_num(pin->number);
uint8_t channel = pwm_gpio_to_channel(pin->number);

int r = pwmout_allocate(slice, channel, variable_frequency, frequency);
if (r != PWMOUT_OK) {
return r;
}

self->slice = slice;
self->channel = channel;

if (target_slice_frequencies[slice] != frequency) {
// Reset the counter and compare values.
pwm_hw->slice[slice].ctr = PWM_CH0_CTR_RESET;
Expand All @@ -157,20 +176,23 @@ bool common_hal_pwmio_pwmout_deinited(pwmio_pwmout_obj_t* self) {
return self->pin == NULL;
}

void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t* self) {
if (common_hal_pwmio_pwmout_deinited(self)) {
return;
}
uint32_t channel_mask = _mask(self->slice, self->channel);
void pwmout_free(uint8_t slice, uint8_t channel) {
uint32_t channel_mask = _mask(slice, channel);
channel_use &= ~channel_mask;
never_reset_channel &= ~channel_mask;
uint32_t slice_mask = ((1 << CHANNELS_PER_SLICE) - 1) << (self->slice * CHANNELS_PER_SLICE);
uint32_t slice_mask = ((1 << CHANNELS_PER_SLICE) - 1) << (slice * CHANNELS_PER_SLICE);
if ((channel_use & slice_mask) == 0) {
target_slice_frequencies[self->slice] = 0;
slice_variable_frequency &= ~(1 << self->slice);
pwm_set_enabled(self->slice, false);
target_slice_frequencies[slice] = 0;
slice_variable_frequency &= ~(1 << slice);
pwm_set_enabled(slice, false);
}
}

void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t* self) {
if (common_hal_pwmio_pwmout_deinited(self)) {
return;
}
pwmout_free(self->slice, self->channel);
reset_pin_number(self->pin->number);
self->pin = NULL;
}
Expand Down
5 changes: 5 additions & 0 deletions ports/raspberrypi/common-hal/pwmio/PWMOut.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,10 @@ typedef struct {
void pwmout_reset(void);
// Private API for AudioPWMOut.
void pwmio_pwmout_set_top(pwmio_pwmout_obj_t* self, uint16_t top);
// Private APIs for RGBMatrix
enum pwmout_result_t pwmout_allocate(uint8_t slice, uint8_t channel, bool variable_frequency, uint32_t frequency);
void pwmout_free(uint8_t slice, uint8_t channel);
void pwmout_never_reset(uint8_t slice, uint8_t channel);
void pwmout_reset_ok(uint8_t slice, uint8_t channel);

#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PWMIO_PWMOUT_H
70 changes: 70 additions & 0 deletions ports/raspberrypi/common-hal/rgbmatrix/RGBMatrix.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
*
* 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 <stddef.h>

#include "py/mphal.h"

#include "common-hal/rgbmatrix/RGBMatrix.h"
#include "shared-bindings/pwmio/PWMOut.h"
#include "shared-module/rgbmatrix/RGBMatrix.h"

#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h"

void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self) {
// Choose a PWM channel based on the first RGB pin
uint8_t slice = pwm_gpio_to_slice_num(self->rgb_pins[0]);
uint8_t channel = pwm_gpio_to_channel(self->rgb_pins[0]);
int result = pwmout_allocate(slice, channel, true, 125000000/3);
if (result == PWMOUT_OK) {
// return value must be nonzero (but slice and channel can both be
// zero), so set bit 16...
pwmout_never_reset(slice, channel);
return (void*)(intptr_t)(slice | (channel << 8) | 0x10000);
}
return NULL;
}

void common_hal_rgbmatrix_timer_enable(void* ptr) {
int8_t slice = ((intptr_t)ptr) & 0xff;
pwm_set_enabled(slice, false);
pwm_clear_irq(slice);
pwm_set_enabled(slice, true);
}

void common_hal_rgbmatrix_timer_disable(void* ptr) {
int8_t slice = ((intptr_t)ptr) & 0xff;
pwm_set_enabled(slice, false);
}

void common_hal_rgbmatrix_timer_free(void* ptr) {
intptr_t value = (intptr_t)ptr;
uint8_t slice = value & 0xff;
uint8_t channel = value >> 8;
pwm_set_enabled(slice, false);
pwmout_free(slice, channel);
return;
}
37 changes: 37 additions & 0 deletions ports/raspberrypi/common-hal/rgbmatrix/RGBMatrix.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
*
* 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.
*/

#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H
#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H

#include "shared-module/rgbmatrix/RGBMatrix.h"

void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self);
void common_hal_rgbmatrix_timer_enable(void*);
void common_hal_rgbmatrix_timer_disable(void*);
void common_hal_rgbmatrix_timer_free(void*);

#endif
Empty file.
2 changes: 2 additions & 0 deletions ports/raspberrypi/mpconfigport.mk
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ else
CIRCUITPY_NEOPIXEL_WRITE = 0
endif

CIRCUITPY_FRAMEBUFFERIO = 1
CIRCUITPY_FULL_BUILD = 1
CIRCUITPY_BITOPS = 1
CIRCUITPY_PWMIO = 1
CIRCUITPY_RGBMATRIX = 1

# Things that need to be implemented.
CIRCUITPY_COUNTIO = 0 # Use PWM interally
Expand Down
2 changes: 1 addition & 1 deletion ports/stm/common-hal/rgbmatrix/RGBMatrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

extern void _PM_IRQ_HANDLER(void);

void *common_hal_rgbmatrix_timer_allocate() {
void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self) {
TIM_TypeDef * timer = stm_peripherals_find_timer();
stm_peripherals_timer_reserve(timer);
stm_peripherals_timer_never_reset(timer);
Expand Down
4 changes: 3 additions & 1 deletion ports/stm/common-hal/rgbmatrix/RGBMatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
#ifndef MICROPY_INCLUDED_STM_COMMON_HAL_RGBMATRIX_RGBMATRIX_H
#define MICROPY_INCLUDED_STM_COMMON_HAL_RGBMATRIX_RGBMATRIX_H

void *common_hal_rgbmatrix_timer_allocate(void);
#include "shared-module/rgbmatrix/RGBMatrix.h"

void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self);
void common_hal_rgbmatrix_timer_enable(void*);
void common_hal_rgbmatrix_timer_disable(void*);
void common_hal_rgbmatrix_timer_free(void*);
Expand Down
2 changes: 1 addition & 1 deletion shared-bindings/pwmio/PWMOut.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

extern const mp_obj_type_t pwmio_pwmout_type;

typedef enum {
typedef enum pwmout_result_t {
PWMOUT_OK,
PWMOUT_INVALID_PIN,
PWMOUT_INVALID_FREQUENCY,
Expand Down
4 changes: 3 additions & 1 deletion shared-module/rgbmatrix/RGBMatrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, i
self->tile = tile;
self->serpentine = serpentine;

self->timer = timer ? timer : common_hal_rgbmatrix_timer_allocate();
self->timer = timer ? timer : common_hal_rgbmatrix_timer_allocate(self);
if (self->timer == NULL) {
mp_raise_ValueError(translate("No timer available"));
}
Expand All @@ -68,6 +68,8 @@ void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, i
}

void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self, mp_obj_t framebuffer) {
self->paused = 1;

common_hal_rgbmatrix_timer_disable(self->timer);
if (framebuffer) {
self->framebuffer = framebuffer;
Expand Down
1 change: 1 addition & 0 deletions shared-module/rgbmatrix/RGBMatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#pragma once

#include "py/obj.h"
#include "lib/protomatter/src/core.h"

extern const mp_obj_type_t rgbmatrix_RGBMatrix_type;
Expand Down