summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony DiCola <tony@tonydicola.com>2016-10-13 04:59:43 +0000
committerTony DiCola <tony@tonydicola.com>2016-10-13 04:59:43 +0000
commit903bc8d04edef0e60fd755e8b9e46ef6a8ec2584 (patch)
treee2273674fa85bb3f848abbf20eb1ca50d1562f15
parent011056af15f6107b9ef35fdf19a3f715b55f55d5 (diff)
atmel-samd: Implement time.ticks_ms function using SysTick timer, add global interrupt enable/disable functions.
-rw-r--r--atmel-samd/main.c3
-rw-r--r--atmel-samd/modutime.c6
-rw-r--r--atmel-samd/mphalport.c32
-rw-r--r--atmel-samd/mphalport.h14
-rw-r--r--atmel-samd/samdneopixel.c6
5 files changed, 58 insertions, 3 deletions
diff --git a/atmel-samd/main.c b/atmel-samd/main.c
index d04983afe..77a0f53fd 100644
--- a/atmel-samd/main.c
+++ b/atmel-samd/main.c
@@ -316,6 +316,9 @@ void samd21_init(void) {
board_init();
+ // SysTick millisecond timer initialization.
+ SysTick_Config(system_cpu_clock_get_hz() / 1000);
+
// Uncomment to init PIN_PA17 for debugging.
// struct port_config pin_conf;
// port_get_config_defaults(&pin_conf);
diff --git a/atmel-samd/modutime.c b/atmel-samd/modutime.c
index 32e6ea229..10be686ad 100644
--- a/atmel-samd/modutime.c
+++ b/atmel-samd/modutime.c
@@ -64,12 +64,18 @@ STATIC mp_obj_t time_sleep_us(mp_obj_t arg) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_us_obj, time_sleep_us);
+STATIC mp_obj_t time_ticks_ms(void) {
+ return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & MP_SMALL_INT_POSITIVE_MASK);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_ms_obj, time_ticks_ms);
+
STATIC const mp_map_elem_t time_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&time_sleep_ms_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&time_sleep_us_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&time_ticks_ms_obj },
};
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
diff --git a/atmel-samd/mphalport.c b/atmel-samd/mphalport.c
index a46af47cd..721f3659e 100644
--- a/atmel-samd/mphalport.c
+++ b/atmel-samd/mphalport.c
@@ -210,3 +210,35 @@ void mp_hal_delay_us(mp_uint_t delay) {
}
delay_us(delay);
}
+
+// Global millisecond tick count (driven by SysTick interrupt handler).
+volatile uint32_t systick_ticks_ms = 0;
+
+void SysTick_Handler(void) {
+ // SysTick interrupt handler called when the SysTick timer reaches zero
+ // (every millisecond).
+ systick_ticks_ms += 1;
+ // Keep the counter within the range of 31 bit uint values since that's the
+ // max value for micropython 'small' ints.
+ systick_ticks_ms = systick_ticks_ms > 2147483647L ? 0 : systick_ticks_ms;
+}
+
+// Interrupt flags that will be saved and restored during disable/Enable
+// interrupt functions below.
+static irqflags_t irq_flags;
+
+void mp_hal_disable_all_interrupts(void) {
+ // Disable all interrupt sources for timing critical sections.
+ // Disable ASF-based interrupts.
+ irq_flags = cpu_irq_save();
+ // Disable SysTick interrupt.
+ SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
+}
+
+void mp_hal_enable_all_interrupts(void) {
+ // Enable all interrupt sources after timing critical sections.
+ // Restore ASF-based interrupts.
+ cpu_irq_restore(irq_flags);
+ // Restore SysTick interrupt.
+ SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
+}
diff --git a/atmel-samd/mphalport.h b/atmel-samd/mphalport.h
index 982960646..0e8635f64 100644
--- a/atmel-samd/mphalport.h
+++ b/atmel-samd/mphalport.h
@@ -27,9 +27,21 @@
#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H__
#define __MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H__
+#include "py/obj.h"
+
#define USB_RX_BUF_SIZE 128
-static inline mp_uint_t mp_hal_ticks_ms(void) { return 0; }
+// Global millisecond tick count (driven by SysTick interrupt).
+extern volatile uint32_t systick_ticks_ms;
+
+static inline mp_uint_t mp_hal_ticks_ms(void) {
+ return systick_ticks_ms;
+}
+
void mp_hal_set_interrupt_char(int c);
+void mp_hal_disable_all_interrupts(void);
+
+void mp_hal_enable_all_interrupts(void);
+
#endif // __MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H__
diff --git a/atmel-samd/samdneopixel.c b/atmel-samd/samdneopixel.c
index 70b27aee7..e271de046 100644
--- a/atmel-samd/samdneopixel.c
+++ b/atmel-samd/samdneopixel.c
@@ -1,6 +1,8 @@
#include "asf/common2/services/delay/delay.h"
#include "asf/sam0/drivers/port/port.h"
+#include "mphalport.h"
+
#include "samdneopixel.h"
void samd_neopixel_write(uint32_t pin, uint8_t *pixels, uint32_t numBytes, bool is800KHz) {
@@ -11,7 +13,7 @@ void samd_neopixel_write(uint32_t pin, uint8_t *pixels, uint32_t numBytes, bool
PortGroup* port;
// Turn off interrupts of any kind during timing-sensitive code.
- irqflags_t flags = cpu_irq_save();
+ mp_hal_disable_all_interrupts();
port = port_get_group_from_gpio_pin(pin);
pinMask = (1UL << (pin % 32)); // From port_pin_set_output_level ASF code.
@@ -78,7 +80,7 @@ void samd_neopixel_write(uint32_t pin, uint8_t *pixels, uint32_t numBytes, bool
}
// Turn on interrupts after timing-sensitive code.
- cpu_irq_restore(flags);
+ mp_hal_enable_all_interrupts();
// 50ms delay to let pixels latch to the data that was just sent.
// This could be optimized to only occur before pixel writes when necessary,