summaryrefslogtreecommitdiff
path: root/ports/stm/peripherals
diff options
context:
space:
mode:
authorLucian Copeland <hierophect@gmail.com>2020-07-01 10:07:45 -0400
committerLucian Copeland <hierophect@gmail.com>2020-07-01 10:35:49 -0400
commitab9a64eafa7f2e5892e13053c5e9490437548263 (patch)
treeb9320fbe9f12ce439412ce6ae655440d7fb92b35 /ports/stm/peripherals
parent6c91af7d5601c0577e9f1909968bbb5aa2bf7b25 (diff)
Add timer allocator, adjust pulsio to use general purpose timers
Diffstat (limited to 'ports/stm/peripherals')
-rw-r--r--ports/stm/peripherals/timers.c136
-rw-r--r--ports/stm/peripherals/timers.h27
2 files changed, 139 insertions, 24 deletions
diff --git a/ports/stm/peripherals/timers.c b/ports/stm/peripherals/timers.c
index 81242f34b..f28b36eec 100644
--- a/ports/stm/peripherals/timers.c
+++ b/ports/stm/peripherals/timers.c
@@ -23,20 +23,51 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "timers.h"
+
+#include "py/mpconfig.h"
+#include "py/gc.h"
+#include "py/obj.h"
+#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
+
+#include "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/microcontroller/Pin.h"
+
+#define ALL_CLOCKS 0xFFFF
static bool stm_timer_reserved[MP_ARRAY_SIZE(mcu_tim_banks)];
static bool stm_timer_never_reset[MP_ARRAY_SIZE(mcu_tim_banks)];
-static void *stm_timer_callback[MP_ARRAY_SIZE(mcu_tim_banks)](void);
-
-STATIC void tim_clock_enable(uint16_t mask);
-STATIC void tim_clock_disable(uint16_t mask);
+static void (*stm_timer_callback[MP_ARRAY_SIZE(mcu_tim_banks)])(void);
+static size_t irq_map[] = {
+ TIM1_CC_IRQn,
+ TIM2_IRQn,
+ TIM3_IRQn,
+ TIM4_IRQn,
+ TIM5_IRQn,
+ TIM6_DAC_IRQn,
+ TIM7_IRQn,
+ TIM8_CC_IRQn,
+ TIM1_BRK_TIM9_IRQn,
+ TIM1_UP_TIM10_IRQn,
+ TIM1_TRG_COM_TIM11_IRQn,
+ TIM8_BRK_TIM12_IRQn,
+ TIM8_UP_TIM13_IRQn,
+ TIM8_TRG_COM_TIM14_IRQn,
+#if (CPY_STM32H7)
+ TIM15_IRQn,
+ TIM16_IRQn,
+ TIM17_IRQn,
+#endif
+};
// Get the frequency (in Hz) of the source clock for the given timer.
// On STM32F405/407/415/417 there are 2 cases for how the clock freq is set.
// If the APB prescaler is 1, then the timer clock is equal to its respective
// APB clock. Otherwise (APB prescaler > 1) the timer clock is twice its
// respective APB clock. See DM00031020 Rev 4, page 115.
-STATIC uint32_t timer_get_source_freq(uint32_t tim_id) {
+uint32_t stm_peripherals_timer_get_source_freq(TIM_TypeDef * timer) {
+ size_t tim_id = stm_peripherals_timer_get_index(timer);
uint32_t source, clk_div;
if (tim_id == 1 || (8 <= tim_id && tim_id <= 11)) {
// TIM{1,8,9,10,11} are on APB2
@@ -54,11 +85,44 @@ STATIC uint32_t timer_get_source_freq(uint32_t tim_id) {
return source;
}
+void timers_reset(void) {
+ uint16_t never_reset_mask = 0x00;
+ for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_tim_banks); i++) {
+ if (!stm_timer_never_reset[i]) {
+ stm_timer_reserved[i] = false;
+ } else {
+ never_reset_mask |= 1 << i;
+ }
+ }
+ tim_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
+}
+
TIM_TypeDef * stm_peripherals_find_timer(void) {
- // TODO: check for unreserved timers from already claimed pins
+ // Check for timers on pins outside the package size
+ // for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_tim_banks); i++) {
+ // bool timer_in_package = false;
+ // // Find each timer instance on the given bank
+ // for (size_t j = 0; j < MP_ARRAY_SIZE(mcu_tim_pin_list); j++) {
+ // // If a pin is claimed, we skip it
+ // if ( (mcu_tim_pin_list[j].tim_index == i)
+ // && (common_hal_mcu_pin_is_free(mcu_tim_pin_list[j].pin) == true) ) {
+ // // Search whether any pins in the package array match it
+ // for (size_t k = 0; k < mcu_pin_globals.map.alloc; k++) {
+ // if ( (mcu_tim_pin_list[j].pin == (mcu_pin_obj_t*)(mcu_pin_globals.map.table[k].value)) ) {
+ // timer_in_package = true;
+ // }
+ // }
+ // }
+ // }
+ // // If no results are found, no unclaimed pins with this timer are in this package,
+ // // and it is safe to pick
+ // if (timer_in_package == false && mcu_tim_banks[i] != NULL) {
+ // return mcu_tim_banks[i];
+ // }
+ // }
// Work backwards - higher index timers have fewer pin allocations
- for (size_t i = MP_ARRAY_SIZE(stm_timer_reserved); i>=0; i--) {
+ for (size_t i = (MP_ARRAY_SIZE(mcu_tim_banks) - 1); i>=0; i--) {
if ((!stm_timer_reserved[i]) && (mcu_tim_banks[i] != NULL)) {
return mcu_tim_banks[i];
}
@@ -67,20 +131,58 @@ TIM_TypeDef * stm_peripherals_find_timer(void) {
return NULL;
}
+void stm_peripherals_timer_preinit(TIM_TypeDef * instance, uint8_t prio, void (*callback)(void)) {
+ size_t tim_idx = stm_peripherals_timer_get_index(instance);
+ stm_timer_callback[tim_idx] = callback;
+ tim_clock_enable(1 << tim_idx);
+ HAL_NVIC_SetPriority(irq_map[tim_idx], prio, 0);
+ HAL_NVIC_EnableIRQ(irq_map[tim_idx]);
+}
+
+void stm_peripherals_timer_reserve(TIM_TypeDef * instance) {
+ size_t tim_idx = stm_peripherals_timer_get_index(instance);
+ stm_timer_reserved[tim_idx] = true;
+}
+
void stm_peripherals_timer_set_callback(void(*callback)(void), TIM_TypeDef * timer) {
- stm_timer_callback[stm_peripherals_timer_get_index]
+ stm_timer_callback[stm_peripherals_timer_get_index(timer)] = callback;
}
void stm_peripherals_timer_free(TIM_TypeDef * instance) {
+ size_t tim_idx = stm_peripherals_timer_get_index(instance);
+ stm_timer_callback[tim_idx] = NULL;
+ tim_clock_disable(1 << tim_idx);
+ stm_timer_reserved[tim_idx] = false;
+ stm_timer_never_reset[tim_idx] = false;
+}
+void stm_peripherals_timer_never_reset(TIM_TypeDef * instance) {
+ size_t tim_idx = stm_peripherals_timer_get_index(instance);
+ stm_timer_never_reset[tim_idx] = true;
+}
+void stm_peripherals_timer_reset_ok(TIM_TypeDef * instance) {
+ size_t tim_idx = stm_peripherals_timer_get_index(instance);
+ stm_timer_never_reset[tim_idx] = false;
+}
+bool stm_peripherals_timer_is_never_reset(TIM_TypeDef * instance){
+ size_t tim_idx = stm_peripherals_timer_get_index(instance);
+ return stm_timer_never_reset[tim_idx];
+}
+bool stm_peripherals_timer_is_reserved(TIM_TypeDef * instance) {
+ size_t tim_idx = stm_peripherals_timer_get_index(instance);
+ return stm_timer_reserved[tim_idx];
+}
+
+size_t stm_peripherals_timer_get_index(TIM_TypeDef * instance) {
+ for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_tim_banks); i++) {
+ if (instance == mcu_tim_banks[i]) {
+ return i;
+ }
+ }
+ return ~(size_t)0;
}
-void stm_peripherals_timer_never_reset(TIM_TypeDef * instance);
-void stm_peripherals_timer_reset_ok(TIM_TypeDef * instance);
-void stm_peripherals_timer_is_never_reset(TIM_TypeDef * instance);
-void stm_peripherals_timer_is_reserved(TIM_TypeDef * instance);
-size_t stm_peripherals_timer_get_index(TIM_TypeDef * instance);
-STATIC void tim_clock_enable(uint16_t mask) {
+void tim_clock_enable(uint16_t mask) {
#ifdef TIM1
if (mask & (1 << 0)) {
__HAL_RCC_TIM1_CLK_ENABLE();
@@ -144,7 +246,7 @@ STATIC void tim_clock_enable(uint16_t mask) {
#endif
}
-STATIC void tim_clock_disable(uint16_t mask) {
+void tim_clock_disable(uint16_t mask) {
#ifdef TIM1
if (mask & (1 << 0)) {
__HAL_RCC_TIM1_CLK_DISABLE();
@@ -209,8 +311,8 @@ STATIC void tim_clock_disable(uint16_t mask) {
}
STATIC void callback_router(size_t index) {
- if (stm_timer_callback[index]) {
- (*stm_timer_callback[index])();
+ if (stm_timer_callback[index - 1]) {
+ (*stm_timer_callback[index - 1])();
}
}
diff --git a/ports/stm/peripherals/timers.h b/ports/stm/peripherals/timers.h
index b0f594b77..8c8a80d53 100644
--- a/ports/stm/peripherals/timers.h
+++ b/ports/stm/peripherals/timers.h
@@ -24,17 +24,30 @@
* THE SOFTWARE.
*/
-typedef struct {
- TIM_TypeDef * p_reg;
- uint8_t instance_id;
- uint8_t cc_channel_count;
-} nrfx_timer_t;
+// typedef struct {
+// TIM_TypeDef * timer;
+// bool reserved;
+// bool never_reset;
+// void (*stm_timer_callback)(void);
+// size_t irq;
+// } stm_timer_t;
+#include <stdint.h>
+#include "py/mphal.h"
+#include "peripherals/periph.h"
+
+#include STM32_HAL_H
+
+void tim_clock_enable(uint16_t mask);
+void tim_clock_disable(uint16_t mask);
+uint32_t stm_peripherals_timer_get_source_freq(TIM_TypeDef * timer);
void timers_reset(void);
TIM_TypeDef * stm_peripherals_find_timer(void);
+void stm_peripherals_timer_preinit(TIM_TypeDef * instance, uint8_t prio, void (*callback)(void));
+void stm_peripherals_timer_reserve(TIM_TypeDef * instance);
void stm_peripherals_timer_free(TIM_TypeDef * instance);
void stm_peripherals_timer_never_reset(TIM_TypeDef * instance);
void stm_peripherals_timer_reset_ok(TIM_TypeDef * instance);
-void stm_peripherals_timer_is_never_reset(TIM_TypeDef * instance);
-void stm_peripherals_timer_is_reserved(TIM_TypeDef * instance);
+bool stm_peripherals_timer_is_never_reset(TIM_TypeDef * instance);
+bool stm_peripherals_timer_is_reserved(TIM_TypeDef * instance);
size_t stm_peripherals_timer_get_index(TIM_TypeDef * instance);