Skip to content

Commit c69b67f

Browse files
authored
Merge pull request adafruit#1277 from dhalbert/nrf-pulseout
PulseOut working
2 parents fe86731 + b3c7746 commit c69b67f

File tree

14 files changed

+281
-35
lines changed

14 files changed

+281
-35
lines changed

ports/nrf/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc
9090
SRC_NRFX = $(addprefix nrfx/,\
9191
drivers/src/nrfx_power.c \
9292
drivers/src/nrfx_spim.c \
93+
drivers/src/nrfx_timer.c \
9394
drivers/src/nrfx_twim.c \
9495
drivers/src/nrfx_uarte.c \
9596
)
@@ -123,6 +124,7 @@ SRC_C += \
123124
peripherals/nrf/clocks.c \
124125
peripherals/nrf/$(MCU_CHIP)/pins.c \
125126
peripherals/nrf/$(MCU_CHIP)/power.c \
127+
peripherals/nrf/timers.c \
126128
supervisor/shared/memory.c
127129

128130
DRIVERS_SRC_C += $(addprefix modules/,\

ports/nrf/common-hal/analogio/AnalogOut.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2013, 2014 Damien P. George
6+
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal

ports/nrf/common-hal/board/__init__.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2013, 2014 Damien P. George
6+
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal

ports/nrf/common-hal/busio/I2C.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ STATIC twim_peripheral_t twim_peripherals[] = {
5656

5757
void i2c_reset(void) {
5858
for (size_t i = 0 ; i < MP_ARRAY_SIZE(twim_peripherals); i++) {
59+
nrf_twim_disable(twim_peripherals[i].twim.p_twim);
5960
twim_peripherals[i].in_use = false;
6061
}
6162
}

ports/nrf/common-hal/busio/UART.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2016 Damien P. George
6+
* Copyright (c) 2018 Ha Thach for Adafruit Industries
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* 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
179179
self->rx_count = -1;
180180
_VERIFY_ERR(nrfx_uarte_rx(&self->uarte, self->buffer, cnt));
181181
}
182-
182+
183183
// queue 1-byte transfer for rx_characters_available()
184184
if ( self->rx_count == 0 ) {
185185
self->rx_count = -1;

ports/nrf/common-hal/pulseio/PWMOut.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
7-
* Copyright (c) 2016 Damien P. George
6+
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
87
*
98
* Permission is hereby granted, free of charge, to any person obtaining a copy
109
* 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,
168167
self->frequency = frequency;
169168
self->variable_frequency = variable_frequency;
170169

170+
// Note this is standard, not strong drive.
171171
nrf_gpio_cfg_output(self->pin_number);
172172

173173
// disable before mapping pin channel

ports/nrf/common-hal/pulseio/PulseOut.c

Lines changed: 114 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2016 Damien P. George
6+
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal
@@ -29,31 +29,136 @@
2929
#include <stdint.h>
3030

3131
#include "mpconfigport.h"
32+
#include "nrf/pins.h"
33+
#include "nrf/timers.h"
3234
#include "py/gc.h"
3335
#include "py/runtime.h"
34-
3536
#include "shared-bindings/pulseio/PulseOut.h"
37+
#include "shared-bindings/pulseio/PWMOut.h"
38+
#include "supervisor/shared/translate.h"
3639

37-
//void pulse_finish(struct tc_module *const module) {
38-
//
39-
//}
40+
// A single timer is shared amongst all PulseOut objects under the assumption that
41+
// the code is single threaded.
42+
static uint8_t refcount = 0;
4043

41-
void pulseout_reset() {
44+
static nrfx_timer_t *timer = NULL;
45+
46+
static uint16_t *pulse_array = NULL;
47+
static volatile uint16_t pulse_array_index = 0;
48+
static uint16_t pulse_array_length;
49+
50+
static void turn_on(pulseio_pulseout_obj_t *pulseout) {
51+
pulseout->pwmout->pwm->PSEL.OUT[0] = pulseout->pwmout->pin_number;
52+
}
53+
54+
static void turn_off(pulseio_pulseout_obj_t *pulseout) {
55+
// Disconnect pin from PWM.
56+
pulseout->pwmout->pwm->PSEL.OUT[0] = 0xffffffff;
57+
// Make sure pin is low.
58+
nrf_gpio_pin_clear(pulseout->pwmout->pin_number);
59+
}
60+
61+
static void start_timer(void) {
62+
nrfx_timer_clear(timer);
63+
// true enables interrupt.
64+
nrfx_timer_compare(timer, NRF_TIMER_CC_CHANNEL0, pulse_array[pulse_array_index], true);
65+
nrfx_timer_resume(timer);
66+
}
67+
68+
static void pulseout_event_handler(nrf_timer_event_t event_type, void *p_context) {
69+
pulseio_pulseout_obj_t *pulseout = (pulseio_pulseout_obj_t*) p_context;
70+
if (event_type != NRF_TIMER_EVENT_COMPARE0) {
71+
// Spurious event.
72+
return;
73+
}
74+
nrfx_timer_pause(timer);
75+
76+
pulse_array_index++;
4277

78+
// No more pulses. Turn off output and don't restart.
79+
if (pulse_array_index >= pulse_array_length) {
80+
turn_off(pulseout);
81+
return;
82+
}
83+
84+
// Alternate on and off, starting with on.
85+
if (pulse_array_index % 2 == 0) {
86+
turn_on(pulseout);
87+
} else {
88+
turn_off(pulseout);
89+
}
90+
91+
// Count up to the next given value.
92+
start_timer();
4393
}
4494

45-
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, const pulseio_pwmout_obj_t* carrier) {
46-
mp_raise_NotImplementedError(NULL);
95+
void pulseout_reset() {
96+
if (timer != NULL) {
97+
nrf_peripherals_free_timer(timer);
98+
}
99+
refcount = 0;
100+
}
101+
102+
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
103+
const pulseio_pwmout_obj_t* carrier) {
104+
if (refcount == 0) {
105+
timer = nrf_peripherals_allocate_timer();
106+
if (timer == NULL) {
107+
mp_raise_RuntimeError(translate("All timers in use"));
108+
}
109+
}
110+
refcount++;
111+
112+
nrfx_timer_config_t timer_config = {
113+
// PulseOut durations are in microseconds, so this is convenient.
114+
.frequency = NRF_TIMER_FREQ_1MHz,
115+
.mode = NRF_TIMER_MODE_TIMER,
116+
.bit_width = NRF_TIMER_BIT_WIDTH_32,
117+
.interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY,
118+
.p_context = self,
119+
};
120+
121+
self->pwmout = carrier;
122+
123+
nrfx_timer_init(timer, &timer_config, &pulseout_event_handler);
124+
turn_off(self);
47125
}
48126

49127
bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) {
50-
return 1;
128+
return self->pwmout == NULL;
51129
}
52130

53131
void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) {
132+
if (common_hal_pulseio_pulseout_deinited(self)) {
133+
return;
134+
}
135+
turn_on(self);
136+
self->pwmout = NULL;
54137

138+
refcount--;
139+
if (refcount == 0) {
140+
nrf_peripherals_free_timer(timer);
141+
}
55142
}
56143

57144
void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) {
145+
pulse_array = pulses;
146+
pulse_array_index = 0;
147+
pulse_array_length = length;
148+
149+
nrfx_timer_enable(timer);
150+
151+
turn_on(self);
152+
// Count up to the next given value.
153+
start_timer();
154+
155+
while(pulse_array_index < length) {
156+
// Do other things while we wait. The interrupts will handle sending the
157+
// signal.
158+
#ifdef MICROPY_VM_HOOK_LOOP
159+
MICROPY_VM_HOOK_LOOP
160+
#endif
161+
}
58162

163+
nrfx_timer_disable(timer);
59164
}

ports/nrf/common-hal/pulseio/PulseOut.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
6+
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal
@@ -28,13 +28,13 @@
2828
#define MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PULSEOUT_H
2929

3030
#include "common-hal/microcontroller/Pin.h"
31+
#include "common-hal/pulseio/PWMOut.h"
3132

3233
#include "py/obj.h"
3334

3435
typedef struct {
3536
mp_obj_base_t base;
36-
// __IO PORT_PINCFG_Type *pincfg;
37-
uint8_t pin;
37+
const pulseio_pwmout_obj_t *pwmout;
3838
} pulseio_pulseout_obj_t;
3939

4040
void pulseout_reset(void);

ports/nrf/nrfx_config.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727

2828
// Enable SPIM2 and SPIM3 (if available)
2929
#define NRFX_SPIM2_ENABLED 1
30-
#ifdef NRF52840_XXAA
30+
#ifdef NRF_SPIM3
3131
#define NRFX_SPIM3_ENABLED 1
32+
#else
33+
#define NRFX_SPIM3_ENABLED 0
3234
#endif
3335

3436

@@ -59,4 +61,24 @@
5961
#define NRFX_PWM3_ENABLED 0
6062
#endif
6163

64+
// TIMERS
65+
#define NRFX_TIMER_ENABLED 1
66+
// Don't enable TIMER0: it's used by the SoftDevice.
67+
#define NRFX_TIMER1_ENABLED 1
68+
#define NRFX_TIMER2_ENABLED 1
69+
70+
#ifdef NRFX_TIMER3
71+
#define NRFX_TIMER3_ENABLED 1
72+
#else
73+
#define NRFX_TIMER3_ENABLED 0
74+
#endif
75+
76+
#ifdef NRFX_TIMER4
77+
#define NRFX_TIMER4_ENABLED 1
78+
#else
79+
#define NRFX_TIMER4_ENABLED 0
80+
#endif
81+
82+
#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 7
83+
6284
#endif // NRFX_CONFIG_H__

ports/nrf/peripherals/nrf/pins.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2013, 2014 Damien P. George
6+
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal

0 commit comments

Comments
 (0)