Skip to content

Ticks ms #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions atmel-samd/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
15 changes: 15 additions & 0 deletions atmel-samd/modutime.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,27 @@ 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 mp_obj_t time_ticks_diff(mp_obj_t start_in, mp_obj_t end_in) {
// we assume that the arguments come from ticks_xx so are small ints
uint32_t start = MP_OBJ_SMALL_INT_VALUE(start_in);
uint32_t end = MP_OBJ_SMALL_INT_VALUE(end_in);
return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(time_ticks_diff_obj, time_ticks_diff);

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 },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&time_ticks_diff_obj },
};

STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
Expand Down
32 changes: 32 additions & 0 deletions atmel-samd/mphalport.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 > (0xFFFFFFFF >> 1) ? 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 SysTick interrupt.
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to swap these two enables so its the reverse order of disable?

// Restore ASF-based interrupts.
cpu_irq_restore(irq_flags);
}
14 changes: 13 additions & 1 deletion atmel-samd/mphalport.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__
6 changes: 4 additions & 2 deletions atmel-samd/samdneopixel.c
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -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.
Expand Down Expand Up @@ -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,
Expand Down