summaryrefslogtreecommitdiff
path: root/ports/atmel-samd
diff options
context:
space:
mode:
authorDaniel Pollard <daniel@learnweaver.com>2020-05-05 15:23:38 +1000
committerDaniel Pollard <daniel@learnweaver.com>2020-05-05 15:23:38 +1000
commitbfa5cd9c13e308df5462653a53fe99eeb0543bc3 (patch)
tree8655ba7f7a099f0705df220260ca0d1453d7e116 /ports/atmel-samd
parent54eb6d39e467e99a214c4ff2b19d061182de4fd0 (diff)
refactor countio based on feedback
Diffstat (limited to 'ports/atmel-samd')
-rw-r--r--ports/atmel-samd/common-hal/countio/Counter.c83
-rw-r--r--ports/atmel-samd/common-hal/countio/Counter.h19
-rw-r--r--ports/atmel-samd/common-hal/countio/__init__.c1
-rw-r--r--ports/atmel-samd/eic_handler.c7
-rw-r--r--ports/atmel-samd/eic_handler.h1
5 files changed, 111 insertions, 0 deletions
diff --git a/ports/atmel-samd/common-hal/countio/Counter.c b/ports/atmel-samd/common-hal/countio/Counter.c
new file mode 100644
index 000000000..db5b325b8
--- /dev/null
+++ b/ports/atmel-samd/common-hal/countio/Counter.c
@@ -0,0 +1,83 @@
+
+#include "common-hal/countio/Counter.h"
+
+#include "atmel_start_pins.h"
+
+#include "eic_handler.h"
+#include "samd/external_interrupts.h"
+#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
+
+void common_hal_countio_counter_construct(countio_counter_obj_t* self,
+ const mcu_pin_obj_t* pin_a) {
+ if (!pin_a->has_extint) {
+ mp_raise_RuntimeError(translate("Pin must support hardware interrupts"));
+ }
+
+
+ if (eic_get_enable()) {
+ if (!eic_channel_free(pin_a->extint_channel)) {
+ mp_raise_RuntimeError(translate("A hardware interrupt channel is already in use"));
+ }
+ } else {
+ turn_on_external_interrupt_controller();
+ }
+
+ // These default settings apply when the EIC isn't yet enabled.
+ self->eic_channel_a = pin_a->extint_channel;
+
+ self->pin_a = pin_a->number;
+
+ gpio_set_pin_function(self->pin_a, GPIO_PIN_FUNCTION_A);
+ gpio_set_pin_pull_mode(self->pin_a, GPIO_PULL_UP);
+
+ set_eic_channel_data(self->eic_channel_a, (void*) self);
+
+ self->count = 0;
+
+
+ claim_pin(pin_a);
+
+
+ set_eic_handler(self->eic_channel_a, EIC_HANDLER_COUNTER);
+ turn_on_eic_channel(self->eic_channel_a, EIC_CONFIG_SENSE0_FALL_Val);
+
+}
+
+bool common_hal_countio_counter_deinited(countio_counter_obj_t* self) {
+ return self->pin_a == NO_PIN;
+}
+
+void common_hal_countio_counter_deinit(countio_counter_obj_t* self) {
+ if (common_hal_countio_counter_deinited(self)) {
+ return;
+ }
+
+ set_eic_handler(self->eic_channel_a, EIC_HANDLER_NO_INTERRUPT);
+ turn_off_eic_channel(self->eic_channel_a);
+
+
+ reset_pin_number(self->pin_a);
+ self->pin_a = NO_PIN;
+
+}
+
+mp_int_t common_hal_countio_counter_get_count(countio_counter_obj_t* self) {
+ return self->count;
+}
+
+void common_hal_countio_counter_set_count(countio_counter_obj_t* self,
+ mp_int_t new_count) {
+ self->count = new_count;
+}
+
+void common_hal_countio_counter_reset(countio_counter_obj_t* self){
+ self->count = 0;
+}
+
+void counter_interrupt_handler(uint8_t channel) {
+ countio_counter_obj_t* self = get_eic_channel_data(channel);
+
+ self->count += 1;
+
+}
diff --git a/ports/atmel-samd/common-hal/countio/Counter.h b/ports/atmel-samd/common-hal/countio/Counter.h
new file mode 100644
index 000000000..724c73415
--- /dev/null
+++ b/ports/atmel-samd/common-hal/countio/Counter.h
@@ -0,0 +1,19 @@
+
+#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_COUNTIO_COUNTER_H
+#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_COUNTIO_COUNTER_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ uint8_t pin_a;
+ uint8_t eic_channel_a:4;
+ mp_int_t count;
+} countio_counter_obj_t;
+
+
+void counter_interrupt_handler(uint8_t channel);
+
+#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_COUNTIO_COUNT_H
diff --git a/ports/atmel-samd/common-hal/countio/__init__.c b/ports/atmel-samd/common-hal/countio/__init__.c
new file mode 100644
index 000000000..b95b20d15
--- /dev/null
+++ b/ports/atmel-samd/common-hal/countio/__init__.c
@@ -0,0 +1 @@
+//No countio module functions
diff --git a/ports/atmel-samd/eic_handler.c b/ports/atmel-samd/eic_handler.c
index 30ecaa7ca..7f26bdefb 100644
--- a/ports/atmel-samd/eic_handler.c
+++ b/ports/atmel-samd/eic_handler.c
@@ -27,6 +27,7 @@
#include "common-hal/pulseio/PulseIn.h"
#include "common-hal/ps2io/Ps2.h"
#include "common-hal/rotaryio/IncrementalEncoder.h"
+#include "common-hal/countio/Counter.h"
#include "shared-bindings/microcontroller/__init__.h"
//#include "samd/external_interrupts.h"
#include "eic_handler.h"
@@ -59,6 +60,12 @@ void shared_eic_handler(uint8_t channel) {
break;
#endif
+#if CIRCUITPY_COUNTIO
+ case EIC_HANDLER_COUNTER:
+ counter_interrupt_handler(channel);
+ break;
+#endif
+
default:
break;
}
diff --git a/ports/atmel-samd/eic_handler.h b/ports/atmel-samd/eic_handler.h
index 71b0fce67..08da7ea34 100644
--- a/ports/atmel-samd/eic_handler.h
+++ b/ports/atmel-samd/eic_handler.h
@@ -30,6 +30,7 @@
#define EIC_HANDLER_PULSEIN 0x1
#define EIC_HANDLER_INCREMENTAL_ENCODER 0x2
#define EIC_HANDLER_PS2 0x3
+#define EIC_HANDLER_COUNTER 0x04
void set_eic_handler(uint8_t channel, uint8_t eic_handler);
void shared_eic_handler(uint8_t channel);