PulseOut working

crypto-aes
Dan Halbert 4 years ago
parent 8d58093328
commit 2262efc311
  1. 2
      ports/nrf/Makefile
  2. 9
      ports/nrf/common-hal/analogio/AnalogOut.c
  3. 2
      ports/nrf/common-hal/board/__init__.c
  4. 1
      ports/nrf/common-hal/busio/I2C.c
  5. 4
      ports/nrf/common-hal/busio/UART.c
  6. 4
      ports/nrf/common-hal/pulseio/PWMOut.c
  7. 123
      ports/nrf/common-hal/pulseio/PulseOut.c
  8. 6
      ports/nrf/common-hal/pulseio/PulseOut.h
  9. 24
      ports/nrf/nrfx_config.h
  10. 2
      ports/nrf/peripherals/nrf/pins.h
  11. 88
      ports/nrf/peripherals/nrf/timers.c
  12. 32
      ports/nrf/peripherals/nrf/timers.h
  13. 19
      ports/nrf/supervisor/port.c
  14. 7
      shared-bindings/pulseio/PulseOut.c

@ -90,6 +90,7 @@ LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc
SRC_NRFX = $(addprefix nrfx/,\
drivers/src/nrfx_power.c \
drivers/src/nrfx_spim.c \
drivers/src/nrfx_timer.c \
drivers/src/nrfx_twim.c \
drivers/src/nrfx_uarte.c \
)
@ -123,6 +124,7 @@ SRC_C += \
peripherals/nrf/clocks.c \
peripherals/nrf/$(MCU_CHIP)/pins.c \
peripherals/nrf/$(MCU_CHIP)/power.c \
peripherals/nrf/timers.c \
supervisor/shared/memory.c
DRIVERS_SRC_C += $(addprefix modules/,\

@ -3,14 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
*
* 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:
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.

@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
* Copyright (c) 2018 Dan Halbert 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

@ -56,6 +56,7 @@ STATIC twim_peripheral_t twim_peripherals[] = {
void i2c_reset(void) {
for (size_t i = 0 ; i < MP_ARRAY_SIZE(twim_peripherals); i++) {
nrf_twim_disable(twim_peripherals[i].twim.p_twim);
twim_peripherals[i].in_use = false;
}
}

@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2016 Damien P. George
* Copyright (c) 2018 Ha Thach 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
@ -179,7 +179,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
self->rx_count = -1;
_VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, cnt));
}
// queue 1-byte transfer for rx_characters_available()
if ( self->rx_count == 0 ) {
self->rx_count = -1;

@ -3,8 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
* Copyright (c) 2016 Damien P. George
* Copyright (c) 2018 Dan Halbert 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
@ -168,6 +167,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
self->frequency = frequency;
self->variable_frequency = variable_frequency;
// Note this is standard, not strong drive.
nrf_gpio_cfg_output(self->pin_number);
// disable before mapping pin channel

@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2016 Damien P. George
* Copyright (c) 2018 Dan Halbert 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
@ -29,31 +29,136 @@
#include <stdint.h>
#include "mpconfigport.h"
#include "nrf/pins.h"
#include "nrf/timers.h"
#include "py/gc.h"
#include "py/runtime.h"
#include "shared-bindings/pulseio/PulseOut.h"
#include "shared-bindings/pulseio/PWMOut.h"
#include "supervisor/shared/translate.h"
//void pulse_finish(struct tc_module *const module) {
//
//}
// A single timer is shared amongst all PulseOut objects under the assumption that
// the code is single threaded.
static uint8_t refcount = 0;
void pulseout_reset() {
static nrfx_timer_t *timer = NULL;
static uint16_t *pulse_array = NULL;
static volatile uint16_t pulse_array_index = 0;
static uint16_t pulse_array_length;
static void turn_on(pulseio_pulseout_obj_t *pulseout) {
pulseout->pwmout->pwm->PSEL.OUT[0] = pulseout->pwmout->pin_number;
}
static void turn_off(pulseio_pulseout_obj_t *pulseout) {
// Disconnect pin from PWM.
pulseout->pwmout->pwm->PSEL.OUT[0] = 0xffffffff;
// Make sure pin is low.
nrf_gpio_pin_clear(pulseout->pwmout->pin_number);
}
static void start_timer(void) {
nrfx_timer_clear(timer);
// true enables interrupt.
nrfx_timer_compare(timer, NRF_TIMER_CC_CHANNEL0, pulse_array[pulse_array_index], true);
nrfx_timer_resume(timer);
}
static void pulseout_event_handler(nrf_timer_event_t event_type, void *p_context) {
pulseio_pulseout_obj_t *pulseout = (pulseio_pulseout_obj_t*) p_context;
if (event_type != NRF_TIMER_EVENT_COMPARE0) {
// Spurious event.
return;
}
nrfx_timer_pause(timer);
pulse_array_index++;
// No more pulses. Turn off output and don't restart.
if (pulse_array_index >= pulse_array_length) {
turn_off(pulseout);
return;
}
// Alternate on and off, starting with on.
if (pulse_array_index % 2 == 0) {
turn_on(pulseout);
} else {
turn_off(pulseout);
}
// Count up to the next given value.
start_timer();
}
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, const pulseio_pwmout_obj_t* carrier) {
mp_raise_NotImplementedError(NULL);
void pulseout_reset() {
if (timer != NULL) {
nrf_peripherals_free_timer(timer);
}
refcount = 0;
}
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
const pulseio_pwmout_obj_t* carrier) {
if (refcount == 0) {
timer = nrf_peripherals_allocate_timer();
if (timer == NULL) {
mp_raise_RuntimeError(translate("All timers in use"));
}
}
refcount++;
nrfx_timer_config_t timer_config = {
// PulseOut durations are in microseconds, so this is convenient.
.frequency = NRF_TIMER_FREQ_1MHz,
.mode = NRF_TIMER_MODE_TIMER,
.bit_width = NRF_TIMER_BIT_WIDTH_32,
.interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY,
.p_context = self,
};
self->pwmout = carrier;
nrfx_timer_init(timer, &timer_config, &pulseout_event_handler);
turn_off(self);
}
bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) {
return 1;
return self->pwmout == NULL;
}
void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) {
if (common_hal_pulseio_pulseout_deinited(self)) {
return;
}
turn_on(self);
self->pwmout = NULL;
refcount--;
if (refcount == 0) {
nrf_peripherals_free_timer(timer);
}
}
void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) {
pulse_array = pulses;
pulse_array_index = 0;
pulse_array_length = length;
nrfx_timer_enable(timer);
turn_on(self);
// Count up to the next given value.
start_timer();
while(pulse_array_index < length) {
// Do other things while we wait. The interrupts will handle sending the
// signal.
#ifdef MICROPY_VM_HOOK_LOOP
MICROPY_VM_HOOK_LOOP
#endif
}
nrfx_timer_disable(timer);
}

@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
* Copyright (c) 2018 Dan Halbert 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
@ -28,13 +28,13 @@
#define MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PULSEOUT_H
#include "common-hal/microcontroller/Pin.h"
#include "common-hal/pulseio/PWMOut.h"
#include "py/obj.h"
typedef struct {
mp_obj_base_t base;
// __IO PORT_PINCFG_Type *pincfg;
uint8_t pin;
const pulseio_pwmout_obj_t *pwmout;
} pulseio_pulseout_obj_t;
void pulseout_reset(void);

@ -27,8 +27,10 @@
// Enable SPIM2 and SPIM3 (if available)
#define NRFX_SPIM2_ENABLED 1
#ifdef NRF52840_XXAA
#ifdef NRF_SPIM3
#define NRFX_SPIM3_ENABLED 1
#else
#define NRFX_SPIM3_ENABLED 0
#endif
@ -59,4 +61,24 @@
#define NRFX_PWM3_ENABLED 0
#endif
// TIMERS
#define NRFX_TIMER_ENABLED 1
// Don't enable TIMER0: it's used by the SoftDevice.
#define NRFX_TIMER1_ENABLED 1
#define NRFX_TIMER2_ENABLED 1
#ifdef NRFX_TIMER3
#define NRFX_TIMER3_ENABLED 1
#else
#define NRFX_TIMER3_ENABLED 0
#endif
#ifdef NRFX_TIMER4
#define NRFX_TIMER4_ENABLED 1
#else
#define NRFX_TIMER4_ENABLED 0
#endif
#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 7
#endif // NRFX_CONFIG_H__

@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
* Copyright (c) 2018 Dan Halbert 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

@ -0,0 +1,88 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Dan Halbert 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 "common-hal/pulseio/PulseOut.h"
#include <stdint.h>
#include "nrfx.h"
#include "nrfx_timer.h"
#include "mpconfigport.h"
#include "py/runtime.h"
STATIC nrfx_timer_t nrfx_timers[] = {
#if NRFX_CHECK(NRFX_TIMER0_ENABLED)
// Note that TIMER0 is reserved for use by the SoftDevice, so it should not usually be enabled.
NRFX_TIMER_INSTANCE(0),
#endif
#if NRFX_CHECK(NRFX_TIMER1_ENABLED)
NRFX_TIMER_INSTANCE(1),
#endif
#if NRFX_CHECK(NRFX_TIMER2_ENABLED)
NRFX_TIMER_INSTANCE(2),
#endif
#if NRFX_CHECK(NRFX_TIMER3_ENABLED)
NRFX_TIMER_INSTANCE(3),
#endif
#if NRFX_CHECK(NRFX_TIMER4_ENABLED)
NRFX_TIMER_INSTANCE(4),
#endif
};
static bool nrfx_timer_allocated[ARRAY_SIZE(nrfx_timers)];
void timers_reset(void) {
for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) {
nrfx_timer_uninit(&nrfx_timers[i]);
nrfx_timer_allocated[i] = false;
}
}
// Returns a free nrfx_timer instance, and marks it as allocated.
// The caller should init as with the desired config.
// Returns NULL if no timer is available.
nrfx_timer_t* nrf_peripherals_allocate_timer(void) {
for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) {
if (!nrfx_timer_allocated[i]) {
nrfx_timer_allocated[i] = true;
return &nrfx_timers[i];
}
}
return NULL;
}
// Free a timer, which may or may not have been initialized.
void nrf_peripherals_free_timer(nrfx_timer_t* timer) {
for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) {
if (timer == &nrfx_timers[i]) {
nrfx_timer_allocated[i] = false;
// Safe to call even if not initialized.
nrfx_timer_uninit(timer);
return;
}
}
}

@ -0,0 +1,32 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Dan Halbert 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 "nrfx.h"
#include "nrfx_timer.h"
void timers_reset(void);
nrfx_timer_t* nrf_peripherals_allocate_timer(void);
void nrf_peripherals_free_timer(nrfx_timer_t* timer);

@ -31,12 +31,14 @@
#include "nrf/cache.h"
#include "nrf/clocks.h"
#include "nrf/power.h"
#include "nrf/timers.h"
#include "shared-module/gamepad/__init__.h"
#include "common-hal/microcontroller/Pin.h"
#include "common-hal/busio/I2C.h"
#include "common-hal/busio/SPI.h"
#include "common-hal/pulseio/PWMOut.h"
#include "common-hal/pulseio/PulseOut.h"
#include "tick.h"
safe_mode_t port_init(void) {
@ -81,6 +83,8 @@ void reset_port(void) {
i2c_reset();
spi_reset();
pwmout_reset();
pulseout_reset();
timers_reset();
reset_all_pins();
}
@ -88,16 +92,7 @@ void reset_port(void) {
void HardFault_Handler(void)
{
// static volatile uint32_t reg;
// static volatile uint32_t reg2;
// static volatile uint32_t bfar;
// reg = SCB->HFSR;
// reg2 = SCB->CFSR;
// bfar = SCB->BFAR;
// for (int i = 0; i < 0; i++)
// {
// (void)reg;
// (void)reg2;
// (void)bfar;
// }
while (true) {
asm("");
}
}

@ -47,7 +47,7 @@
//|
//| .. class:: PulseOut(carrier)
//|
//| Create a PulseOut object associated with the given PWM out experience.
//| Create a PulseOut object associated with the given PWMout object.
//|
//| :param ~pulseio.PWMOut carrier: PWMOut that is set to output on the desired pin.
//|
@ -57,9 +57,10 @@
//| import pulseio
//| import board
//|
//| pwm = pulseio.PWMOut(board.D13, duty_cycle=2 ** 15)
//| # 50% duty cycle at 38kHz.
//| pwm = pulseio.PWMOut(board.D13, frequency=38000, duty_cycle=32768)
//| pulse = pulseio.PulseOut(pwm)
//| # on off on off on
//| # on off on off on
//| pulses = array.array('H', [65000, 1000, 65000, 65000, 1000])
//| pulse.send(pulses)
//|

Loading…
Cancel
Save