Add PulseOut
This commit is contained in:
parent
98469322b7
commit
f9512983ff
@ -29,32 +29,52 @@
|
||||
#include "shared-bindings/pulseio/PWMOut.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
// STATIC void turn_on(pulseio_pulseout_obj_t *pulseout) {
|
||||
// }
|
||||
|
||||
// STATIC void turn_off(pulseio_pulseout_obj_t *pulseout) {
|
||||
// }
|
||||
|
||||
// STATIC void start_timer(void) {
|
||||
// }
|
||||
|
||||
// STATIC void pulseout_event_handler(void) {
|
||||
// }
|
||||
|
||||
void pulseout_reset() {
|
||||
}
|
||||
// Requires rmt.c void esp32s2_peripherals_reset_all(void) to reset
|
||||
|
||||
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
|
||||
const pulseio_pwmout_obj_t* carrier) {
|
||||
mp_raise_NotImplementedError(translate("PulseOut not supported on this chip"));
|
||||
const mcu_pin_obj_t* pin,
|
||||
uint32_t frequency) {
|
||||
|
||||
rmt_channel_t channel = esp32s2_peripherals_find_and_reserve_rmt();
|
||||
|
||||
// Configure Channel
|
||||
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(pin->number, channel);
|
||||
config.tx_config.carrier_en = true;
|
||||
config.tx_config.carrier_duty_percent = 50;
|
||||
config.tx_config.carrier_freq_hz = frequency;
|
||||
config.clk_div = 80;
|
||||
|
||||
rmt_config(&config);
|
||||
rmt_driver_install(channel, 0, 0);
|
||||
|
||||
self->channel = channel;
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) {
|
||||
return false;
|
||||
return (self->channel == RMT_CHANNEL_MAX);
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) {
|
||||
esp32s2_peripherals_free_rmt(self->channel);
|
||||
self->channel = RMT_CHANNEL_MAX;
|
||||
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) {
|
||||
rmt_item32_t items[length];
|
||||
|
||||
// Circuitpython allows 16 bit pulse values, while ESP32 only allows 15 bits
|
||||
// Thus, we use entire items for one pulse, rather than switching inside each item
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
// Setting the RMT duration to 0 has undefined behavior, so avoid that pre-emptively.
|
||||
if (pulses[i] == 0) {
|
||||
pulses[i] = 1;
|
||||
}
|
||||
uint32_t level = (i % 2) ? 0 : 1;
|
||||
const rmt_item32_t item = {{{ (pulses[i] & 0x8000 ? 0x7FFF : 1), level, (pulses[i] & 0x7FFF), level}}};
|
||||
items[i] = item;
|
||||
}
|
||||
|
||||
rmt_write_items(self->channel, items, length, true);
|
||||
rmt_wait_tx_done(self->channel, pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
@ -29,14 +29,14 @@
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "common-hal/pulseio/PWMOut.h"
|
||||
#include "driver/rmt.h"
|
||||
#include "rmt.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
pulseio_pwmout_obj_t *pwmout;
|
||||
rmt_channel_t channel;
|
||||
} pulseio_pulseout_obj_t;
|
||||
|
||||
void pulseout_reset(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_PULSEIO_PULSEOUT_H
|
||||
|
@ -28,19 +28,20 @@
|
||||
#ifndef ESP32S2_MPCONFIGPORT_H__
|
||||
#define ESP32S2_MPCONFIGPORT_H__
|
||||
|
||||
#define CIRCUITPY_INTERNAL_NVM_SIZE (0)
|
||||
#define MICROPY_NLR_THUMB (0)
|
||||
#define CIRCUITPY_INTERNAL_NVM_SIZE (0)
|
||||
#define MICROPY_NLR_THUMB (0)
|
||||
|
||||
#define MICROPY_PY_UJSON (0)
|
||||
#define MICROPY_USE_INTERNAL_PRINTF (0)
|
||||
#define MICROPY_PY_UJSON (0)
|
||||
#define MICROPY_USE_INTERNAL_PRINTF (0)
|
||||
|
||||
#include "py/circuitpy_mpconfig.h"
|
||||
|
||||
#define CPY_PULSEOUT_USES_DIGITALIO (1)
|
||||
|
||||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
CIRCUITPY_COMMON_ROOT_POINTERS
|
||||
#define MICROPY_NLR_SETJMP (1)
|
||||
#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000
|
||||
#define MICROPY_NLR_SETJMP (1)
|
||||
#define CIRCUITPY_DEFAULT_STACK_SIZE (0x6000)
|
||||
|
||||
|
||||
#endif // __INCLUDED_ESP32S2_MPCONFIGPORT_H
|
||||
|
@ -29,6 +29,14 @@
|
||||
|
||||
bool rmt_reserved_channels[RMT_CHANNEL_MAX];
|
||||
|
||||
void esp32s2_peripherals_rmt_reset(void) {
|
||||
for (size_t i = 0; i < RMT_CHANNEL_MAX; i++) {
|
||||
if (rmt_reserved_channels[i]) {
|
||||
esp32s2_peripherals_free_rmt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rmt_channel_t esp32s2_peripherals_find_and_reserve_rmt(void) {
|
||||
for (size_t i = 0; i < RMT_CHANNEL_MAX; i++) {
|
||||
if (!rmt_reserved_channels[i]) {
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "driver/rmt.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void esp32s2_peripherals_rmt_reset(void);
|
||||
rmt_channel_t esp32s2_peripherals_find_and_reserve_rmt(void);
|
||||
void esp32s2_peripherals_free_rmt(rmt_channel_t chan);
|
||||
|
||||
|
@ -42,6 +42,8 @@
|
||||
#include "supervisor/memory.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
|
||||
#include "rmt.h"
|
||||
|
||||
STATIC esp_timer_handle_t _tick_timer;
|
||||
|
||||
void tick_timer_cb(void* arg) {
|
||||
@ -66,6 +68,7 @@ void reset_port(void) {
|
||||
vTaskDelay(4);
|
||||
|
||||
#if CIRCUITPY_PULSEIO
|
||||
esp32s2_peripherals_rmt_reset();
|
||||
pwmout_reset();
|
||||
#endif
|
||||
#if CIRCUITPY_BUSIO
|
||||
|
@ -64,19 +64,33 @@
|
||||
//| pulse.send(pulses)"""
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
mp_arg_check_num(n_args, kw_args, 1, 1, false);
|
||||
mp_obj_t carrier_obj = args[0];
|
||||
STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
|
||||
if (!MP_OBJ_IS_TYPE(carrier_obj, &pulseio_pwmout_type)) {
|
||||
mp_raise_TypeError_varg(translate("Expected a %q"), pulseio_pwmout_type.name);
|
||||
}
|
||||
|
||||
// create Pulse object from the given pin
|
||||
pulseio_pulseout_obj_t *self = m_new_obj(pulseio_pulseout_obj_t);
|
||||
self->base.type = &pulseio_pulseout_type;
|
||||
|
||||
#ifndef CPY_PULSEOUT_USES_DIGITALIO
|
||||
// Most ports pass a PWMOut
|
||||
mp_arg_check_num(n_args, kw_args, 1, 1, false);
|
||||
mp_obj_t carrier_obj = args[0];
|
||||
if (!MP_OBJ_IS_TYPE(carrier_obj, &pulseio_pwmout_type)) {
|
||||
mp_raise_TypeError_varg(translate("Expected a %q"), pulseio_pwmout_type.name);
|
||||
}
|
||||
common_hal_pulseio_pulseout_construct(self, (pulseio_pwmout_obj_t *)MP_OBJ_TO_PTR(carrier_obj));
|
||||
#else
|
||||
// ESP32-S2 Special Case
|
||||
enum { ARG_pin, ARG_frequency};
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 38000} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
const mcu_pin_obj_t* pin = validate_obj_is_free_pin(args[ARG_pin].u_obj);
|
||||
|
||||
common_hal_pulseio_pulseout_construct(self, pin, args[ARG_frequency].u_int);
|
||||
#endif
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
@ -33,8 +33,14 @@
|
||||
|
||||
extern const mp_obj_type_t pulseio_pulseout_type;
|
||||
|
||||
#ifndef CPY_PULSEOUT_USES_DIGITALIO
|
||||
extern void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
|
||||
const pulseio_pwmout_obj_t* carrier);
|
||||
#else
|
||||
extern void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
|
||||
const mcu_pin_obj_t* pin, uint32_t frequency);
|
||||
#endif
|
||||
|
||||
extern void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self);
|
||||
extern bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self);
|
||||
extern void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self,
|
||||
|
Loading…
Reference in New Issue
Block a user