From 211b44e6304a61aa6cf130e35806cb72356bec72 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 29 Sep 2017 13:58:13 -0700 Subject: [PATCH] Update `time` to use SysTick (#274) * atmel-samd: Add time back using the SysTick counter in the core. Fixes #261 * Switch to SysTick_Config --- atmel-samd/Makefile | 6 +- .../asf4_conf/samd21/peripheral_clk_config.h | 2 +- .../common-hal/microcontroller/Processor.c | 5 +- atmel-samd/mpconfigport.h | 6 +- atmel-samd/mphalport.c | 3 +- atmel-samd/supervisor/port.c | 2 - atmel-samd/tick.c | 76 ++++++++++++------- atmel-samd/tick.h | 2 + 8 files changed, 61 insertions(+), 41 deletions(-) diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile index 7792b3bdc8..49bd087225 100644 --- a/atmel-samd/Makefile +++ b/atmel-samd/Makefile @@ -213,11 +213,12 @@ SRC_C = \ SRC_COMMON_HAL = \ board/__init__.c \ + digitalio/__init__.c \ + digitalio/DigitalInOut.c \ microcontroller/__init__.c \ microcontroller/Pin.c \ microcontroller/Processor.c \ - digitalio/__init__.c \ - digitalio/DigitalInOut.c + time/__init__.c # analogio/__init__.c \ analogio/AnalogIn.c \ analogio/AnalogOut.c \ @@ -238,7 +239,6 @@ SRC_COMMON_HAL = \ pulseio/PulseOut.c \ pulseio/PWMOut.c \ storage/__init__.c \ - time/__init__.c \ touchio/__init__.c \ touchio/TouchIn.c \ usb_hid/__init__.c \ diff --git a/atmel-samd/asf4_conf/samd21/peripheral_clk_config.h b/atmel-samd/asf4_conf/samd21/peripheral_clk_config.h index c0831aae9c..b38052a1b1 100644 --- a/atmel-samd/asf4_conf/samd21/peripheral_clk_config.h +++ b/atmel-samd/asf4_conf/samd21/peripheral_clk_config.h @@ -41,7 +41,7 @@ * \brief CPU's Clock frequency */ #ifndef CONF_CPU_FREQUENCY -#define CONF_CPU_FREQUENCY 1000000 +#define CONF_CPU_FREQUENCY 48000000 #endif // Core Clock Source diff --git a/atmel-samd/common-hal/microcontroller/Processor.c b/atmel-samd/common-hal/microcontroller/Processor.c index a037c42db6..21bc9aed0c 100644 --- a/atmel-samd/common-hal/microcontroller/Processor.c +++ b/atmel-samd/common-hal/microcontroller/Processor.c @@ -63,6 +63,7 @@ #include "common-hal/microcontroller/Processor.h" +#include "peripheral_clk_config.h" // #define ADC_TEMP_SAMPLE_LENGTH 4 // #define INT1V_VALUE_FLOAT 1.0 @@ -226,6 +227,6 @@ float common_hal_mcu_processor_get_temperature(void) { uint32_t common_hal_mcu_processor_get_frequency(void) { - return 0; - //return system_cpu_clock_get_hz(); + // TODO(tannewt): Determine this dynamically. + return CONF_CPU_FREQUENCY; } diff --git a/atmel-samd/mpconfigport.h b/atmel-samd/mpconfigport.h index 96c0acd003..8881803e4e 100644 --- a/atmel-samd/mpconfigport.h +++ b/atmel-samd/mpconfigport.h @@ -203,7 +203,6 @@ extern const struct _mp_obj_module_t usb_hid_module; // { MP_OBJ_NEW_QSTR(MP_QSTR_touchio), (mp_obj_t)&touchio_module }, // { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, // { MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, -// { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, // { MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write),(mp_obj_t)&neopixel_write_module }, // { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, // { MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&os_module }, @@ -213,9 +212,10 @@ extern const struct _mp_obj_module_t usb_hid_module; #define MICROPY_PORT_BUILTIN_MODULES \ - { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, \ - { MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, EXTRA_BUILTIN_MODULES #define MICROPY_PORT_BUILTIN_DEBUG_MODULES \ diff --git a/atmel-samd/mphalport.c b/atmel-samd/mphalport.c index 2010639293..6ac66c9d14 100644 --- a/atmel-samd/mphalport.c +++ b/atmel-samd/mphalport.c @@ -18,6 +18,7 @@ #include "mpconfigboard.h" #include "mphalport.h" #include "reset.h" +#include "tick.h" #include "usb.h" extern struct usart_module usart_instance; @@ -64,7 +65,7 @@ void mp_hal_delay_ms(mp_uint_t delay) { } void mp_hal_delay_us(mp_uint_t delay) { - delay_us(delay); + tick_delay(delay); } void mp_hal_disable_all_interrupts(void) { diff --git a/atmel-samd/supervisor/port.c b/atmel-samd/supervisor/port.c index 998ad59a4d..4ff5d0e1db 100644 --- a/atmel-samd/supervisor/port.c +++ b/atmel-samd/supervisor/port.c @@ -89,8 +89,6 @@ safe_mode_t port_init(void) { init_mcu(); - delay_init(SysTick); - board_init(); // Configure millisecond timer initialization. diff --git a/atmel-samd/tick.c b/atmel-samd/tick.c index 1828341e5e..c34f1d2af6 100644 --- a/atmel-samd/tick.c +++ b/atmel-samd/tick.c @@ -1,24 +1,40 @@ - - -#include - -#include "hal/include/hal_timer.h" -#include "hpl/pm/hpl_pm_base.h" -#include "hpl/tc/hpl_tc_base.h" -#include "hpl/gclk/hpl_gclk_base.h" -#include "include/component/gclk.h" - -#include "supervisor/shared/autoreload.h" +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include "tick.h" +#include "peripheral_clk_config.h" + +#include "supervisor/shared/autoreload.h" +#include "shared-bindings/microcontroller/Processor.h" + // Global millisecond tick count volatile uint64_t ticks_ms = 0; -struct timer_descriptor ms_timer; -//static struct timer_task task; - -void timer_tick(const struct timer_task *const timer_task) { +void SysTick_Handler(void) { // SysTick interrupt handler called when the SysTick timer reaches zero // (every millisecond). ticks_ms += 1; @@ -29,18 +45,20 @@ void timer_tick(const struct timer_task *const timer_task) { } void tick_init() { - #ifdef SAMD21 - _pm_enable_bus_clock(PM_BUS_APBC, TC5); - #endif - // _gclk_enable_channel(TC5_GCLK_ID, GCLK_SOURCE_DFLL48M); - - // timer_init(&ms_timer, TC5, _tc_get_timer()); - - // timer_set_clock_cycles_per_tick(&ms_timer, 48000000 / 1000 - 1); - // task.cb = timer_tick; - // task.interval = 1; - // task.mode = TIMER_TASK_REPEAT; - // timer_add_task(&ms_timer, &task); - // - // timer_start(&ms_timer); + uint32_t ticks_per_ms = common_hal_mcu_processor_get_frequency() / 1000; + SysTick_Config(ticks_per_ms); + NVIC_EnableIRQ(SysTick_IRQn); +} + +void tick_delay(uint32_t us) { + uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; + uint32_t us_between_ticks = SysTick->VAL / ticks_per_us; + uint64_t start_ms = ticks_ms; + while (us > 1000) { + while (ticks_ms == start_ms) {} + us -= us_between_ticks; + start_ms = ticks_ms; + us_between_ticks = 1000; + } + while (SysTick->VAL > ((1000 - us) * ticks_per_us)) {} } diff --git a/atmel-samd/tick.h b/atmel-samd/tick.h index f842fd2855..a987ff7ad2 100644 --- a/atmel-samd/tick.h +++ b/atmel-samd/tick.h @@ -34,4 +34,6 @@ extern struct timer_descriptor ms_timer; void tick_init(void); +void tick_delay(uint32_t us); + #endif // MICROPY_INCLUDED_ATMEL_SAMD_TICK_H