Skip to content

Commit d451f69

Browse files
authored
Merge pull request adafruit#9 from adafruit/ticks_ms
Support ticks in os.
2 parents 011056a + 2ee52c4 commit d451f69

File tree

5 files changed

+67
-3
lines changed

5 files changed

+67
-3
lines changed

atmel-samd/main.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,9 @@ void samd21_init(void) {
316316

317317
board_init();
318318

319+
// SysTick millisecond timer initialization.
320+
SysTick_Config(system_cpu_clock_get_hz() / 1000);
321+
319322
// Uncomment to init PIN_PA17 for debugging.
320323
// struct port_config pin_conf;
321324
// port_get_config_defaults(&pin_conf);

atmel-samd/modutime.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,27 @@ STATIC mp_obj_t time_sleep_us(mp_obj_t arg) {
6464
}
6565
STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_us_obj, time_sleep_us);
6666

67+
STATIC mp_obj_t time_ticks_ms(void) {
68+
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & MP_SMALL_INT_POSITIVE_MASK);
69+
}
70+
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_ms_obj, time_ticks_ms);
71+
72+
STATIC mp_obj_t time_ticks_diff(mp_obj_t start_in, mp_obj_t end_in) {
73+
// we assume that the arguments come from ticks_xx so are small ints
74+
uint32_t start = MP_OBJ_SMALL_INT_VALUE(start_in);
75+
uint32_t end = MP_OBJ_SMALL_INT_VALUE(end_in);
76+
return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK);
77+
}
78+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(time_ticks_diff_obj, time_ticks_diff);
79+
6780
STATIC const mp_map_elem_t time_module_globals_table[] = {
6881
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
6982

7083
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj },
7184
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&time_sleep_ms_obj },
7285
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&time_sleep_us_obj },
86+
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&time_ticks_ms_obj },
87+
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&time_ticks_diff_obj },
7388
};
7489

7590
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);

atmel-samd/mphalport.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,35 @@ void mp_hal_delay_us(mp_uint_t delay) {
210210
}
211211
delay_us(delay);
212212
}
213+
214+
// Global millisecond tick count (driven by SysTick interrupt handler).
215+
volatile uint32_t systick_ticks_ms = 0;
216+
217+
void SysTick_Handler(void) {
218+
// SysTick interrupt handler called when the SysTick timer reaches zero
219+
// (every millisecond).
220+
systick_ticks_ms += 1;
221+
// Keep the counter within the range of 31 bit uint values since that's the
222+
// max value for micropython 'small' ints.
223+
systick_ticks_ms = systick_ticks_ms > (0xFFFFFFFF >> 1) ? 0 : systick_ticks_ms;
224+
}
225+
226+
// Interrupt flags that will be saved and restored during disable/Enable
227+
// interrupt functions below.
228+
static irqflags_t irq_flags;
229+
230+
void mp_hal_disable_all_interrupts(void) {
231+
// Disable all interrupt sources for timing critical sections.
232+
// Disable ASF-based interrupts.
233+
irq_flags = cpu_irq_save();
234+
// Disable SysTick interrupt.
235+
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
236+
}
237+
238+
void mp_hal_enable_all_interrupts(void) {
239+
// Enable all interrupt sources after timing critical sections.
240+
// Restore SysTick interrupt.
241+
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
242+
// Restore ASF-based interrupts.
243+
cpu_irq_restore(irq_flags);
244+
}

atmel-samd/mphalport.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,21 @@
2727
#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H__
2828
#define __MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H__
2929

30+
#include "py/obj.h"
31+
3032
#define USB_RX_BUF_SIZE 128
3133

32-
static inline mp_uint_t mp_hal_ticks_ms(void) { return 0; }
34+
// Global millisecond tick count (driven by SysTick interrupt).
35+
extern volatile uint32_t systick_ticks_ms;
36+
37+
static inline mp_uint_t mp_hal_ticks_ms(void) {
38+
return systick_ticks_ms;
39+
}
40+
3341
void mp_hal_set_interrupt_char(int c);
3442

43+
void mp_hal_disable_all_interrupts(void);
44+
45+
void mp_hal_enable_all_interrupts(void);
46+
3547
#endif // __MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H__

atmel-samd/samdneopixel.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "asf/common2/services/delay/delay.h"
22
#include "asf/sam0/drivers/port/port.h"
33

4+
#include "mphalport.h"
5+
46
#include "samdneopixel.h"
57

68
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
1113
PortGroup* port;
1214

1315
// Turn off interrupts of any kind during timing-sensitive code.
14-
irqflags_t flags = cpu_irq_save();
16+
mp_hal_disable_all_interrupts();
1517

1618
port = port_get_group_from_gpio_pin(pin);
1719
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
7880
}
7981

8082
// Turn on interrupts after timing-sensitive code.
81-
cpu_irq_restore(flags);
83+
mp_hal_enable_all_interrupts();
8284

8385
// 50ms delay to let pixels latch to the data that was just sent.
8486
// This could be optimized to only occur before pixel writes when necessary,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy