Expand PulseOut API, debug cleanup
This commit is contained in:
parent
88fcc19e24
commit
0fc730bc5a
|
@ -96,7 +96,15 @@ void pulseout_reset() {
|
|||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
|
||||
const pulseio_pwmout_obj_t* carrier) {
|
||||
const pulseio_pwmout_obj_t* carrier,
|
||||
const mcu_pin_obj_t* pin,
|
||||
uint32_t frequency,
|
||||
uint16_t duty_cycle) {
|
||||
if (!carrier || pin || frequency) {
|
||||
mp_raise_NotImplementedError(translate("Port does not accept pins or frequency. \
|
||||
Construct and pass a PWM Carrier instead"));
|
||||
}
|
||||
|
||||
if (refcount == 0) {
|
||||
// Find a spare timer.
|
||||
Tc *tc = NULL;
|
||||
|
|
|
@ -58,8 +58,16 @@ static bool pulseout_timer_handler(unsigned int *next_interval_us, void *arg)
|
|||
return true;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t *self,
|
||||
const pulseio_pwmout_obj_t *carrier) {
|
||||
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
|
||||
const pulseio_pwmout_obj_t* carrier,
|
||||
const mcu_pin_obj_t* pin,
|
||||
uint32_t frequency,
|
||||
uint16_t duty_cycle) {
|
||||
if (!carrier || pin || frequency) {
|
||||
mp_raise_NotImplementedError(translate("Port does not accept pins or frequency. \
|
||||
Construct and pass a PWM Carrier instead"));
|
||||
}
|
||||
|
||||
if (pulse_fd < 0) {
|
||||
pulse_fd = open("/dev/timer0", O_RDONLY);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*/
|
||||
|
||||
#include "common-hal/pulseio/PulseIn.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
STATIC uint8_t refcount = 0;
|
||||
|
@ -33,17 +34,11 @@ STATIC pulseio_pulsein_obj_t * handles[RMT_CHANNEL_MAX];
|
|||
// Requires rmt.c void esp32s2_peripherals_reset_all(void) to reset
|
||||
|
||||
STATIC void update_internal_buffer(pulseio_pulsein_obj_t* self) {
|
||||
//mp_printf(&mp_plat_print, "Update internal Buffer\n");
|
||||
uint32_t length = 0;
|
||||
rmt_item32_t *items = (rmt_item32_t *) xRingbufferReceive(self->buf_handle, &length, 0);
|
||||
if (items) {
|
||||
length /= 4;
|
||||
//mp_printf(&mp_plat_print, "Length%d\n",length);
|
||||
// TODO: If the size of the recieve is larger than the buffer, reset it?
|
||||
|
||||
for (size_t i=0; i < length; i++) {
|
||||
//mp_printf(&mp_plat_print, "Item d0:%d, l0:%d, d1:%d, l1:%d\n",(items[i].duration0 * 3),
|
||||
// items[i].level0,(items[i].duration1 * 3),items[i].level1);
|
||||
uint16_t pos = (self->start + self->len) % self->maxlen;
|
||||
self->buffer[pos] = items[i].duration0 * 3;
|
||||
// Check if second item exists before incrementing
|
||||
|
@ -69,25 +64,16 @@ STATIC void update_internal_buffer(pulseio_pulsein_obj_t* self) {
|
|||
// We can't access the RMT interrupt, so we need a global service to prevent
|
||||
// the ringbuffer from overflowing and crashing the peripheral
|
||||
void pulsein_background(void) {
|
||||
//mp_printf(&mp_plat_print, "BG Task!\n");
|
||||
for (size_t i = 0; i < RMT_CHANNEL_MAX; i++) {
|
||||
if (handles[i]) {
|
||||
//mp_printf(&mp_plat_print, "Located viable handle:%d\n",i);
|
||||
update_internal_buffer(handles[i]);
|
||||
UBaseType_t items_waiting;
|
||||
vRingbufferGetInfo(handles[i]->buf_handle, NULL, NULL, NULL, NULL, &items_waiting);
|
||||
//mp_printf(&mp_plat_print, "items waiting:%d\n",items_waiting);
|
||||
// if (items_waiting > handles[i]->maxlen) {
|
||||
// mp_printf(&mp_plat_print, "Overage!\n");
|
||||
// mp_printf(&mp_plat_print, "Items waiting detected:%d\n", items_waiting);
|
||||
// update_internal_buffer(handles[i]);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pulsein_reset(void) {
|
||||
mp_printf(&mp_plat_print, "Pulsein Reset called\n");
|
||||
for (size_t i = 0; i < RMT_CHANNEL_MAX; i++) {
|
||||
handles[i] = NULL;
|
||||
}
|
||||
|
@ -103,48 +89,48 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu
|
|||
}
|
||||
self->pin = pin;
|
||||
self->maxlen = maxlen;
|
||||
// self->idle_state = idle_state;
|
||||
self->idle_state = idle_state;
|
||||
self->start = 0;
|
||||
self->len = 0;
|
||||
// self->first_edge = true;
|
||||
self->paused = false;
|
||||
// self->last_overflow = 0;
|
||||
// self->last_count = 0;
|
||||
|
||||
// Set pull settings
|
||||
gpio_pullup_dis(pin->number);
|
||||
gpio_pulldown_dis(pin->number);
|
||||
if (idle_state) {
|
||||
gpio_pullup_en(pin->number);
|
||||
} else {
|
||||
gpio_pulldown_en(pin->number);
|
||||
}
|
||||
|
||||
// Find a free RMT Channel and configure it
|
||||
rmt_channel_t channel = esp32s2_peripherals_find_and_reserve_rmt();
|
||||
mp_printf(&mp_plat_print, "Selected Channel:%d!\n",channel);
|
||||
|
||||
// Configure Channel
|
||||
rmt_config_t config = RMT_DEFAULT_CONFIG_RX(pin->number, channel);
|
||||
config.rx_config.filter_en = true;
|
||||
config.rx_config.idle_threshold = 30000;
|
||||
config.clk_div = 240;
|
||||
|
||||
config.rx_config.idle_threshold = 30000; // 30*3=90ms idle required to register a sequence
|
||||
config.clk_div = 240; // All measurements are divided by 3 to accomodate 65ms pulses
|
||||
rmt_config(&config);
|
||||
size_t len = 1000; //TODO: pick a reasonable number for this?
|
||||
// size_t len = maxlen * 4;
|
||||
rmt_driver_install(channel, len, 0);
|
||||
rmt_driver_install(channel, 1000, 0); //TODO: pick a more specific buffer size?
|
||||
|
||||
// Store this object and the buffer handle for background updates
|
||||
self->channel = channel;
|
||||
|
||||
// Store handle for background updates
|
||||
handles[channel] = self;
|
||||
|
||||
rmt_get_ringbuf_handle(channel, &(self->buf_handle));
|
||||
rmt_rx_start(channel, true);
|
||||
|
||||
// start RMT RX, and enable ticks so the core doesn't turn off.
|
||||
rmt_rx_start(channel, true);
|
||||
supervisor_enable_tick();
|
||||
refcount++;
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) {
|
||||
return handles[self->channel] ? true : false;
|
||||
return handles[self->channel] ? false : true;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) {
|
||||
handles[self->channel] = NULL;
|
||||
esp32s2_peripherals_free_rmt(self->channel);
|
||||
reset_pin_number(self->pin);
|
||||
reset_pin_number(self->pin->number);
|
||||
refcount--;
|
||||
if (refcount == 0) {
|
||||
supervisor_disable_tick();
|
||||
|
@ -153,7 +139,7 @@ void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) {
|
|||
|
||||
void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) {
|
||||
self->paused = true;
|
||||
rmt_rx_stop();
|
||||
rmt_rx_stop(self->channel);
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t trigger_duration) {
|
||||
|
@ -162,17 +148,25 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t tri
|
|||
common_hal_pulseio_pulsein_pause(self);
|
||||
}
|
||||
|
||||
if (trigger_duration > 0) {
|
||||
gpio_set_direction(self->pin->number, GPIO_MODE_DEF_OUTPUT);
|
||||
gpio_set_level(self->pin->number, !self->idle_state);
|
||||
common_hal_mcu_delay_us((uint32_t)trigger_duration);
|
||||
gpio_set_level(self->pin->number, self->idle_state);
|
||||
gpio_set_direction(self->pin->number, GPIO_MODE_INPUT); // should revert to pull direction
|
||||
}
|
||||
|
||||
self->paused = false;
|
||||
rmt_rx_start();
|
||||
rmt_rx_start(self->channel, false);
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) {
|
||||
// Buffer only updates in BG tasks or fetches, so no extra protection is needed
|
||||
self->start = 0;
|
||||
self->len = 0;
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) {
|
||||
//mp_printf(&mp_plat_print, "Call GetItem\n");
|
||||
update_internal_buffer(self);
|
||||
if (index < 0) {
|
||||
index += self->len;
|
||||
|
@ -185,7 +179,6 @@ uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_
|
|||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) {
|
||||
mp_printf(&mp_plat_print, "Call PopLeft\n");
|
||||
update_internal_buffer(self);
|
||||
|
||||
if (self->len == 0) {
|
||||
|
@ -197,28 +190,6 @@ uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) {
|
|||
self->len--;
|
||||
|
||||
return value;
|
||||
|
||||
|
||||
// uint32_t length = 0;
|
||||
// rmt_item32_t *items = (rmt_item32_t *) xRingbufferReceive(self->buf_handle, &length, 10);
|
||||
// mp_printf(&mp_plat_print, "Length%d\n",length);
|
||||
// if (items) {
|
||||
// length /= 4;
|
||||
// mp_printf(&mp_plat_print, "Length%d\n",length);
|
||||
// for (size_t i=0; i < length; i++) {
|
||||
// mp_printf(&mp_plat_print, "Item d0:%d, l0:%d, d1:%d, l1:%d\n",(items[i].duration0 * 3),
|
||||
// items[i].level0,(items[i].duration1 * 3),items[i].level1);
|
||||
// }
|
||||
// vRingbufferReturnItem(self->buf_handle, (void *) items);
|
||||
// }
|
||||
// // while(items) {
|
||||
// // mp_printf(&mp_plat_print, "Length%d",length);
|
||||
// // mp_printf(&mp_plat_print, "Item val0:%d, val1:%d, val:%d",items->duration0,
|
||||
// // items->duration1,items->val);
|
||||
// // vRingbufferReturnItem(self->buf_handle, (void *) items);
|
||||
// // items = (rmt_item32_t *) xRingbufferReceive(self->buf_handle, &length, 1);
|
||||
// // }
|
||||
// return items ? items[0].duration0 : false;
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) {
|
||||
|
|
|
@ -42,15 +42,12 @@ typedef struct {
|
|||
bool paused;
|
||||
|
||||
RingbufHandle_t buf_handle;
|
||||
volatile bool first_edge;
|
||||
|
||||
uint16_t* buffer;
|
||||
uint16_t maxlen;
|
||||
|
||||
volatile uint16_t start;
|
||||
volatile uint16_t len;
|
||||
volatile uint32_t last_overflow;
|
||||
volatile uint16_t last_count;
|
||||
} pulseio_pulsein_obj_t;
|
||||
|
||||
void pulsein_reset(void);
|
||||
|
|
|
@ -32,15 +32,21 @@
|
|||
// Requires rmt.c void esp32s2_peripherals_reset_all(void) to reset
|
||||
|
||||
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
|
||||
const mcu_pin_obj_t* pin,
|
||||
uint32_t frequency) {
|
||||
const pulseio_pwmout_obj_t* carrier,
|
||||
const mcu_pin_obj_t* pin,
|
||||
uint32_t frequency,
|
||||
uint16_t duty_cycle) {
|
||||
if (carrier || !pin || !frequency) {
|
||||
mp_raise_NotImplementedError(translate("Port does not accept PWM carrier. \
|
||||
Pass a pin, frequency and duty cycle instead"));
|
||||
}
|
||||
|
||||
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_duty_percent = (duty_cycle * 100) / (1<<16);
|
||||
config.tx_config.carrier_freq_hz = frequency;
|
||||
config.clk_div = 80;
|
||||
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
|
||||
#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)
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
bool rmt_reserved_channels[RMT_CHANNEL_MAX];
|
||||
|
||||
void esp32s2_peripherals_rmt_reset(void) {
|
||||
mp_printf(&mp_plat_print, "RMT Reset called\n");
|
||||
for (size_t i = 0; i < RMT_CHANNEL_MAX; i++) {
|
||||
if (rmt_reserved_channels[i]) {
|
||||
esp32s2_peripherals_free_rmt(i);
|
||||
|
|
|
@ -94,7 +94,10 @@ void pulseout_reset() {
|
|||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
|
||||
const pulseio_pwmout_obj_t* carrier) {
|
||||
const pulseio_pwmout_obj_t* carrier,
|
||||
const mcu_pin_obj_t* pin,
|
||||
uint32_t frequency,
|
||||
uint16_t duty_cycle) {
|
||||
// if (refcount == 0) {
|
||||
// // Find a spare timer.
|
||||
// Tc *tc = NULL;
|
||||
|
|
|
@ -100,7 +100,15 @@ void pulseout_reset() {
|
|||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
|
||||
const pulseio_pwmout_obj_t* carrier) {
|
||||
const pulseio_pwmout_obj_t* carrier,
|
||||
const mcu_pin_obj_t* pin,
|
||||
uint32_t frequency,
|
||||
uint16_t duty_cycle) {
|
||||
if (!carrier || pin || frequency) {
|
||||
mp_raise_NotImplementedError(translate("Port does not accept pins or frequency. \
|
||||
Construct and pass a PWM Carrier instead"));
|
||||
}
|
||||
|
||||
if (refcount == 0) {
|
||||
timer = nrf_peripherals_allocate_timer_or_throw();
|
||||
}
|
||||
|
|
|
@ -113,7 +113,15 @@ void pulseout_reset() {
|
|||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
|
||||
const pulseio_pwmout_obj_t* carrier) {
|
||||
const pulseio_pwmout_obj_t* carrier,
|
||||
const mcu_pin_obj_t* pin,
|
||||
uint32_t frequency,
|
||||
uint16_t duty_cycle) {
|
||||
if (!carrier || pin || frequency) {
|
||||
mp_raise_NotImplementedError(translate("Port does not accept pins or frequency. \
|
||||
Construct and pass a PWM Carrier instead"));
|
||||
}
|
||||
|
||||
// Add to active PulseOuts
|
||||
refcount++;
|
||||
TIM_TypeDef * tim_instance = stm_peripherals_find_timer();
|
||||
|
|
|
@ -69,29 +69,24 @@ STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_ar
|
|||
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);
|
||||
mp_obj_t carrier_obj = pos_args[0];
|
||||
if (MP_OBJ_IS_TYPE(carrier_obj, &pulseio_pwmout_type)) {
|
||||
// PWM Carrier
|
||||
mp_arg_check_num(n_args, kw_args, 1, 1, false);
|
||||
common_hal_pulseio_pulseout_construct(self, (pulseio_pwmout_obj_t *)MP_OBJ_TO_PTR(carrier_obj), NULL, 0, 0);
|
||||
} else {
|
||||
// Pin and Frequency
|
||||
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_QSTR_duty_cycle, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1<<15} },
|
||||
};
|
||||
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, NULL, pin, args[ARG_frequency].u_int, args[ARG_frequency].u_int);
|
||||
}
|
||||
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,13 +33,11 @@
|
|||
|
||||
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
|
||||
const pulseio_pwmout_obj_t* carrier,
|
||||
const mcu_pin_obj_t* pin,
|
||||
uint32_t frequency,
|
||||
uint16_t duty_cycle);
|
||||
|
||||
extern void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self);
|
||||
extern bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self);
|
||||
|
|
Loading…
Reference in New Issue