stmhal: Add timer module; move servo PWM from TIM2 to TIM5.
As per issue #257, servo is better on TIM5 because TIM2 is connected to more GPIO.
This commit is contained in:
parent
69dee59ce4
commit
a12be917a4
|
@ -61,6 +61,7 @@ SRC_C = \
|
||||||
usbd_msc_storage.c \
|
usbd_msc_storage.c \
|
||||||
pendsv.c \
|
pendsv.c \
|
||||||
systick.c \
|
systick.c \
|
||||||
|
timer.c \
|
||||||
led.c \
|
led.c \
|
||||||
pin.c \
|
pin.c \
|
||||||
pin_map.c \
|
pin_map.c \
|
||||||
|
@ -98,7 +99,6 @@ SRC_C = \
|
||||||
adc.c \
|
adc.c \
|
||||||
i2c.c \
|
i2c.c \
|
||||||
|
|
||||||
# timer.c \
|
|
||||||
# pybwlan.c \
|
# pybwlan.c \
|
||||||
|
|
||||||
SRC_S = \
|
SRC_S = \
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stm32f4xx_hal.h>
|
#include <stm32f4xx_hal.h>
|
||||||
#include "usbd_cdc_msc_hid.h"
|
|
||||||
#include "usbd_cdc_interface.h"
|
|
||||||
|
|
||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
@ -9,6 +7,7 @@
|
||||||
#include "qstr.h"
|
#include "qstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
|
#include "timer.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
#include "pin.h"
|
#include "pin.h"
|
||||||
#include "build/pins.h"
|
#include "build/pins.h"
|
||||||
|
@ -54,6 +53,8 @@ void led_init(void) {
|
||||||
// LED4 (blue) is on PB4 which is TIM3_CH1
|
// LED4 (blue) is on PB4 which is TIM3_CH1
|
||||||
// we use PWM on this channel to fade the LED
|
// we use PWM on this channel to fade the LED
|
||||||
|
|
||||||
|
// LED3 (yellow) is on PA15 which has TIM2_CH1, so we could PWM that as well
|
||||||
|
|
||||||
// GPIO configuration
|
// GPIO configuration
|
||||||
GPIO_InitStructure.Pin = MICROPY_HW_LED4.pin_mask;
|
GPIO_InitStructure.Pin = MICROPY_HW_LED4.pin_mask;
|
||||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "readline.h"
|
#include "readline.h"
|
||||||
#include "pyexec.h"
|
#include "pyexec.h"
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
|
#include "timer.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
#include "exti.h"
|
#include "exti.h"
|
||||||
#include "usrsw.h"
|
#include "usrsw.h"
|
||||||
|
@ -38,7 +39,6 @@
|
||||||
#include "dac.h"
|
#include "dac.h"
|
||||||
#include "pin.h"
|
#include "pin.h"
|
||||||
#if 0
|
#if 0
|
||||||
#include "timer.h"
|
|
||||||
#include "pybwlan.h"
|
#include "pybwlan.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -177,6 +177,7 @@ int main(void) {
|
||||||
|
|
||||||
// basic sub-system init
|
// basic sub-system init
|
||||||
pendsv_init();
|
pendsv_init();
|
||||||
|
timer_tim3_init();
|
||||||
led_init();
|
led_init();
|
||||||
switch_init0();
|
switch_init0();
|
||||||
|
|
||||||
|
@ -409,6 +410,11 @@ soft_reset:
|
||||||
rng_init();
|
rng_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_HW_ENABLE_TIMER
|
||||||
|
// timer
|
||||||
|
//timer_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
// I2C
|
// I2C
|
||||||
i2c_init();
|
i2c_init();
|
||||||
|
|
||||||
|
@ -422,13 +428,6 @@ soft_reset:
|
||||||
servo_init();
|
servo_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
#if MICROPY_HW_ENABLE_TIMER
|
|
||||||
// timer
|
|
||||||
timer_init();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MICROPY_HW_ENABLE_DAC
|
#if MICROPY_HW_ENABLE_DAC
|
||||||
// DAC
|
// DAC
|
||||||
dac_init();
|
dac_init();
|
||||||
|
|
|
@ -8,12 +8,13 @@
|
||||||
#include "qstr.h"
|
#include "qstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
|
#include "timer.h"
|
||||||
#include "servo.h"
|
#include "servo.h"
|
||||||
|
|
||||||
// this servo driver uses hardware PWM to drive servos on PA0, PA1, PA2, PA3 = X1, X2, X3, X4
|
// this servo driver uses hardware PWM to drive servos on PA0, PA1, PA2, PA3 = X1, X2, X3, X4
|
||||||
// TIM2 and TIM5 have CH1, CH2, CH3, CH4 on PA0-PA3 respectively
|
// TIM2 and TIM5 have CH1, CH2, CH3, CH4 on PA0-PA3 respectively
|
||||||
// they are both 32-bit counters with 16-bit prescaler
|
// they are both 32-bit counters with 16-bit prescaler
|
||||||
// we use TIM2
|
// we use TIM5
|
||||||
|
|
||||||
#define PYB_SERVO_NUM (4)
|
#define PYB_SERVO_NUM (4)
|
||||||
|
|
||||||
|
@ -30,23 +31,8 @@ STATIC const mp_obj_type_t servo_obj_type;
|
||||||
|
|
||||||
STATIC pyb_servo_obj_t pyb_servo_obj[PYB_SERVO_NUM];
|
STATIC pyb_servo_obj_t pyb_servo_obj[PYB_SERVO_NUM];
|
||||||
|
|
||||||
TIM_HandleTypeDef TIM2_Handle;
|
|
||||||
|
|
||||||
void servo_init(void) {
|
void servo_init(void) {
|
||||||
// TIM2 clock enable
|
timer_tim5_init();
|
||||||
__TIM2_CLK_ENABLE();
|
|
||||||
|
|
||||||
// set up and enable interrupt
|
|
||||||
HAL_NVIC_SetPriority(TIM2_IRQn, 6, 0);
|
|
||||||
HAL_NVIC_EnableIRQ(TIM2_IRQn);
|
|
||||||
|
|
||||||
// PWM clock configuration
|
|
||||||
TIM2_Handle.Instance = TIM2;
|
|
||||||
TIM2_Handle.Init.Period = 2000; // timer cycles at 50Hz
|
|
||||||
TIM2_Handle.Init.Prescaler = ((SystemCoreClock / 2) / 100000) - 1; // timer runs at 100kHz
|
|
||||||
TIM2_Handle.Init.ClockDivision = 0;
|
|
||||||
TIM2_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
|
||||||
HAL_TIM_PWM_Init(&TIM2_Handle);
|
|
||||||
|
|
||||||
// reset servo objects
|
// reset servo objects
|
||||||
for (int i = 0; i < PYB_SERVO_NUM; i++) {
|
for (int i = 0; i < PYB_SERVO_NUM; i++) {
|
||||||
|
@ -74,17 +60,17 @@ void servo_timer_irq_callback(void) {
|
||||||
need_it = true;
|
need_it = true;
|
||||||
}
|
}
|
||||||
switch (s->servo_id) {
|
switch (s->servo_id) {
|
||||||
case 1: TIM2->CCR1 = s->pulse_cur; break;
|
case 1: TIM5->CCR1 = s->pulse_cur; break;
|
||||||
case 2: TIM2->CCR2 = s->pulse_cur; break;
|
case 2: TIM5->CCR2 = s->pulse_cur; break;
|
||||||
case 3: TIM2->CCR3 = s->pulse_cur; break;
|
case 3: TIM5->CCR3 = s->pulse_cur; break;
|
||||||
case 4: TIM2->CCR4 = s->pulse_cur; break;
|
case 4: TIM5->CCR4 = s->pulse_cur; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (need_it) {
|
if (need_it) {
|
||||||
__HAL_TIM_ENABLE_IT(&TIM2_Handle, TIM_IT_UPDATE);
|
__HAL_TIM_ENABLE_IT(&TIM5_Handle, TIM_IT_UPDATE);
|
||||||
} else {
|
} else {
|
||||||
__HAL_TIM_DISABLE_IT(&TIM2_Handle, TIM_IT_UPDATE);
|
__HAL_TIM_DISABLE_IT(&TIM5_Handle, TIM_IT_UPDATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +91,7 @@ STATIC void servo_init_channel(pyb_servo_obj_t *s) {
|
||||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||||
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
|
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
|
||||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||||
GPIO_InitStructure.Alternate = GPIO_AF1_TIM2;
|
GPIO_InitStructure.Alternate = GPIO_AF2_TIM5;
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||||
|
|
||||||
// PWM mode configuration
|
// PWM mode configuration
|
||||||
|
@ -114,10 +100,10 @@ STATIC void servo_init_channel(pyb_servo_obj_t *s) {
|
||||||
oc_init.Pulse = s->pulse_cur; // units of 10us
|
oc_init.Pulse = s->pulse_cur; // units of 10us
|
||||||
oc_init.OCPolarity = TIM_OCPOLARITY_HIGH;
|
oc_init.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||||
oc_init.OCFastMode = TIM_OCFAST_DISABLE;
|
oc_init.OCFastMode = TIM_OCFAST_DISABLE;
|
||||||
HAL_TIM_PWM_ConfigChannel(&TIM2_Handle, &oc_init, channel);
|
HAL_TIM_PWM_ConfigChannel(&TIM5_Handle, &oc_init, channel);
|
||||||
|
|
||||||
// start PWM
|
// start PWM
|
||||||
HAL_TIM_PWM_Start(&TIM2_Handle, channel);
|
HAL_TIM_PWM_Start(&TIM5_Handle, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -129,10 +115,10 @@ STATIC mp_obj_t pyb_servo_set(mp_obj_t port, mp_obj_t value) {
|
||||||
if (v < 50) { v = 50; }
|
if (v < 50) { v = 50; }
|
||||||
if (v > 250) { v = 250; }
|
if (v > 250) { v = 250; }
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case 1: TIM2->CCR1 = v; break;
|
case 1: TIM5->CCR1 = v; break;
|
||||||
case 2: TIM2->CCR2 = v; break;
|
case 2: TIM5->CCR2 = v; break;
|
||||||
case 3: TIM2->CCR3 = v; break;
|
case 3: TIM5->CCR3 = v; break;
|
||||||
case 4: TIM2->CCR4 = v; break;
|
case 4: TIM5->CCR4 = v; break;
|
||||||
}
|
}
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
@ -142,8 +128,8 @@ MP_DEFINE_CONST_FUN_OBJ_2(pyb_servo_set_obj, pyb_servo_set);
|
||||||
STATIC mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse) {
|
STATIC mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse) {
|
||||||
int pe = mp_obj_get_int(period);
|
int pe = mp_obj_get_int(period);
|
||||||
int pu = mp_obj_get_int(pulse);
|
int pu = mp_obj_get_int(pulse);
|
||||||
TIM2->ARR = pe;
|
TIM5->ARR = pe;
|
||||||
TIM2->CCR3 = pu;
|
TIM5->CCR3 = pu;
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
extern TIM_HandleTypeDef TIM2_Handle;
|
|
||||||
|
|
||||||
void servo_init(void);
|
void servo_init(void);
|
||||||
void servo_timer_irq_callback(void);
|
void servo_timer_irq_callback(void);
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,6 @@
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "stm32f4xx_hal.h"
|
#include "stm32f4xx_hal.h"
|
||||||
#include "usbd_cdc_msc_hid.h"
|
|
||||||
#include "usbd_cdc_interface.h"
|
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
@ -47,30 +45,12 @@
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "servo.h"
|
#include "servo.h"
|
||||||
|
|
||||||
TIM_HandleTypeDef TIM3_Handle;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the Global MSP.
|
* @brief Initializes the Global MSP.
|
||||||
* @param None
|
* @param None
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_MspInit(void) {
|
void HAL_MspInit(void) {
|
||||||
// set up the timer for USBD CDC
|
|
||||||
__TIM3_CLK_ENABLE();
|
|
||||||
|
|
||||||
TIM3_Handle.Instance = TIM3;
|
|
||||||
TIM3_Handle.Init.Period = (USBD_CDC_POLLING_INTERVAL*1000) - 1;
|
|
||||||
TIM3_Handle.Init.Prescaler = 84-1;
|
|
||||||
TIM3_Handle.Init.ClockDivision = 0;
|
|
||||||
TIM3_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
|
||||||
HAL_TIM_Base_Init(&TIM3_Handle);
|
|
||||||
|
|
||||||
HAL_NVIC_SetPriority(TIM3_IRQn, 6, 0);
|
|
||||||
HAL_NVIC_EnableIRQ(TIM3_IRQn);
|
|
||||||
|
|
||||||
if (HAL_TIM_Base_Start(&TIM3_Handle) != HAL_OK) {
|
|
||||||
/* Starting Error */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,9 +59,6 @@ void HAL_MspInit(void) {
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_MspDeInit(void) {
|
void HAL_MspDeInit(void) {
|
||||||
// reset TIM3 timer
|
|
||||||
__TIM3_FORCE_RESET();
|
|
||||||
__TIM3_RELEASE_RESET();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,14 +123,6 @@ void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc)
|
||||||
__HAL_RCC_RTC_DISABLE();
|
__HAL_RCC_RTC_DISABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
|
||||||
if (htim == &TIM3_Handle) {
|
|
||||||
USBD_CDC_HAL_TIM_PeriodElapsedCallback();
|
|
||||||
} else if (htim == &TIM2_Handle) {
|
|
||||||
servo_timer_irq_callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -42,15 +42,13 @@
|
||||||
|
|
||||||
#include "stm32f4xx_it.h"
|
#include "stm32f4xx_it.h"
|
||||||
#include "stm32f4xx_hal.h"
|
#include "stm32f4xx_hal.h"
|
||||||
#include "usbd_cdc_msc_hid.h"
|
|
||||||
#include "usbd_cdc_interface.h"
|
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
#include "qstr.h"
|
#include "qstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "exti.h"
|
#include "exti.h"
|
||||||
#include "servo.h"
|
#include "timer.h"
|
||||||
|
|
||||||
/** @addtogroup STM32F4xx_HAL_Examples
|
/** @addtogroup STM32F4xx_HAL_Examples
|
||||||
* @{
|
* @{
|
||||||
|
@ -351,12 +349,12 @@ void RTC_WKUP_IRQHandler(void) {
|
||||||
Handle_EXTI_Irq(EXTI_RTC_WAKEUP);
|
Handle_EXTI_Irq(EXTI_RTC_WAKEUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIM2_IRQHandler(void) {
|
|
||||||
HAL_TIM_IRQHandler(&TIM2_Handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TIM3_IRQHandler(void) {
|
void TIM3_IRQHandler(void) {
|
||||||
HAL_TIM_IRQHandler(&TIM3_Handle);
|
HAL_TIM_IRQHandler(&TIM3_Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TIM5_IRQHandler(void) {
|
||||||
|
HAL_TIM_IRQHandler(&TIM5_Handle);
|
||||||
|
}
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <stm32f4xx_hal.h>
|
||||||
|
#include "usbd_cdc_msc_hid.h"
|
||||||
|
#include "usbd_cdc_interface.h"
|
||||||
|
|
||||||
|
#include "nlr.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "mpconfig.h"
|
||||||
|
#include "qstr.h"
|
||||||
|
#include "obj.h"
|
||||||
|
#include "runtime.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "servo.h"
|
||||||
|
|
||||||
|
// The timers can be used by multiple drivers, and need a common point for
|
||||||
|
// the interrupts to be dispatched, so they are all collected here.
|
||||||
|
//
|
||||||
|
// TIM3:
|
||||||
|
// - USB CDC interface, interval, to check for new data
|
||||||
|
// - LED 4, PWM to set the LED intensity
|
||||||
|
//
|
||||||
|
// TIM5:
|
||||||
|
// - servo controller, PWM
|
||||||
|
|
||||||
|
TIM_HandleTypeDef TIM3_Handle;
|
||||||
|
TIM_HandleTypeDef TIM5_Handle;
|
||||||
|
|
||||||
|
// TIM3 is set-up for the USB CDC interface
|
||||||
|
void timer_tim3_init(void) {
|
||||||
|
// set up the timer for USBD CDC
|
||||||
|
__TIM3_CLK_ENABLE();
|
||||||
|
|
||||||
|
TIM3_Handle.Instance = TIM3;
|
||||||
|
TIM3_Handle.Init.Period = (USBD_CDC_POLLING_INTERVAL*1000) - 1;
|
||||||
|
TIM3_Handle.Init.Prescaler = 84-1;
|
||||||
|
TIM3_Handle.Init.ClockDivision = 0;
|
||||||
|
TIM3_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
|
HAL_TIM_Base_Init(&TIM3_Handle);
|
||||||
|
|
||||||
|
HAL_NVIC_SetPriority(TIM3_IRQn, 6, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(TIM3_IRQn);
|
||||||
|
|
||||||
|
if (HAL_TIM_Base_Start(&TIM3_Handle) != HAL_OK) {
|
||||||
|
/* Starting Error */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unused
|
||||||
|
void timer_tim3_deinit(void) {
|
||||||
|
// reset TIM3 timer
|
||||||
|
__TIM3_FORCE_RESET();
|
||||||
|
__TIM3_RELEASE_RESET();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TIM5 is set-up for the servo controller
|
||||||
|
void timer_tim5_init(void) {
|
||||||
|
// TIM5 clock enable
|
||||||
|
__TIM5_CLK_ENABLE();
|
||||||
|
|
||||||
|
// set up and enable interrupt
|
||||||
|
HAL_NVIC_SetPriority(TIM5_IRQn, 6, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(TIM5_IRQn);
|
||||||
|
|
||||||
|
// PWM clock configuration
|
||||||
|
TIM5_Handle.Instance = TIM5;
|
||||||
|
TIM5_Handle.Init.Period = 2000; // timer cycles at 50Hz
|
||||||
|
TIM5_Handle.Init.Prescaler = ((SystemCoreClock / 2) / 100000) - 1; // timer runs at 100kHz
|
||||||
|
TIM5_Handle.Init.ClockDivision = 0;
|
||||||
|
TIM5_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
|
HAL_TIM_PWM_Init(&TIM5_Handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interrupt dispatch
|
||||||
|
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
||||||
|
if (htim == &TIM3_Handle) {
|
||||||
|
USBD_CDC_HAL_TIM_PeriodElapsedCallback();
|
||||||
|
} else if (htim == &TIM5_Handle) {
|
||||||
|
servo_timer_irq_callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// below is old code from stm/ which has not yet been fully ported to stmhal/
|
||||||
|
#if 0
|
||||||
|
typedef struct _pyb_hal_tim_t {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
TIM_HandleTypeDef htim;
|
||||||
|
} pyb_hal_tim_t;
|
||||||
|
|
||||||
|
pyb_hal_tim_t pyb_hal_tim_6;
|
||||||
|
|
||||||
|
pyb_hal_tim_6 = {
|
||||||
|
.base = {&pyb_type_hal_tim};
|
||||||
|
.htim = {TIM6
|
||||||
|
|
||||||
|
// TIM6 is used as an internal interrup to schedule something at a specific rate
|
||||||
|
mp_obj_t timer_py_callback;
|
||||||
|
|
||||||
|
mp_obj_t timer_py_set_callback(mp_obj_t f) {
|
||||||
|
timer_py_callback = f;
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t timer_py_set_period(mp_obj_t period) {
|
||||||
|
TIM6->ARR = mp_obj_get_int(period) & 0xffff;
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t timer_py_set_prescaler(mp_obj_t prescaler) {
|
||||||
|
TIM6->PSC = mp_obj_get_int(prescaler) & 0xffff;
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t timer_py_get_value(void) {
|
||||||
|
return mp_obj_new_int(TIM6->CNT & 0xfffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_init(void) {
|
||||||
|
timer_py_callback = mp_const_none;
|
||||||
|
|
||||||
|
// TIM6 clock enable
|
||||||
|
__TIM6_CLK_ENABLE();
|
||||||
|
|
||||||
|
// Compute the prescaler value so TIM6 runs at 20kHz
|
||||||
|
uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 20000) - 1;
|
||||||
|
|
||||||
|
// Time base configuration
|
||||||
|
tim_handle.Instance = TIM6;
|
||||||
|
tim_handle.Init.Prescaler = PrescalerValue;
|
||||||
|
tim_handle.Init.CounterMode = TIM_COUNTERMODE_UP; // unused for TIM6
|
||||||
|
tim_handle.Init.Period = 20000; // timer cycles at 1Hz
|
||||||
|
tim_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // unused for TIM6
|
||||||
|
tim_handle.Init.RepetitionCounter = 0; // unused for TIM6
|
||||||
|
HAL_TIM_Base_Init(&tim_handle);
|
||||||
|
|
||||||
|
// enable perhipheral preload register
|
||||||
|
//TIM_ARRPreloadConfig(TIM6, ENABLE); ??
|
||||||
|
|
||||||
|
// set up interrupt
|
||||||
|
HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 0xf, 0xf); // lowest priority
|
||||||
|
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
|
||||||
|
|
||||||
|
// start timer, so that it interrupts on overflow
|
||||||
|
HAL_TIM_Base_Start_IT(&tim_handle);
|
||||||
|
|
||||||
|
// Python interface
|
||||||
|
mp_obj_t m = mp_obj_new_module(QSTR_FROM_STR_STATIC("timer"));
|
||||||
|
rt_store_attr(m, QSTR_FROM_STR_STATIC("callback"), rt_make_function_n(1, timer_py_set_callback));
|
||||||
|
rt_store_attr(m, QSTR_FROM_STR_STATIC("period"), rt_make_function_n(1, timer_py_set_period));
|
||||||
|
rt_store_attr(m, QSTR_FROM_STR_STATIC("prescaler"), rt_make_function_n(1, timer_py_set_prescaler));
|
||||||
|
rt_store_attr(m, QSTR_FROM_STR_STATIC("value"), rt_make_function_n(0, timer_py_get_value));
|
||||||
|
rt_store_name(QSTR_FROM_STR_STATIC("timer"), m);
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_interrupt(void) {
|
||||||
|
if (timer_py_callback != mp_const_none) {
|
||||||
|
nlr_buf_t nlr;
|
||||||
|
if (nlr_push(&nlr) == 0) {
|
||||||
|
// XXX what to do if the GC is in the middle of running??
|
||||||
|
rt_call_function_0(timer_py_callback);
|
||||||
|
nlr_pop();
|
||||||
|
} else {
|
||||||
|
// uncaught exception
|
||||||
|
printf("exception in timer interrupt\n");
|
||||||
|
mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t pyb_Timer(mp_obj_t timx_in) {
|
||||||
|
TIM_TypeDef *TIMx = (TIM_TypeDef*)mp_obj_get_int(timx_in);
|
||||||
|
if (!IS_TIM_INSTANCE(TIMx)) {
|
||||||
|
nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "argument 1 is not a TIM instance"));
|
||||||
|
}
|
||||||
|
pyb_hal_tim_t *tim = m_new_obj(pyb_hal_tim_t);
|
||||||
|
tim->htim.Instance = TIMx;
|
||||||
|
tim->htim.Instance.Init.Prescaler = x;
|
||||||
|
tim->htim.Instance.Init.CounterMode = y;
|
||||||
|
tim->htim.Instance.Init.Period = y;
|
||||||
|
tim->htim.Instance.Init.ClockDivision = y;
|
||||||
|
tim->htim.Instance.Init.RepetitionCounter = y;
|
||||||
|
HAL_TIM_Base_Init(&tim->htim);
|
||||||
|
return tim;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Periodically, the state of the buffer "UserTxBuffer" is checked.
|
||||||
|
// The period depends on USBD_CDC_POLLING_INTERVAL
|
||||||
|
// The value is in ms. The max is 65 and the min is 1.
|
||||||
|
#define USBD_CDC_POLLING_INTERVAL (10)
|
||||||
|
|
||||||
|
extern TIM_HandleTypeDef TIM3_Handle;
|
||||||
|
extern TIM_HandleTypeDef TIM5_Handle;
|
||||||
|
|
||||||
|
void timer_tim3_init(void);
|
||||||
|
void timer_tim5_init(void);
|
|
@ -33,10 +33,6 @@
|
||||||
/* Exported types ------------------------------------------------------------*/
|
/* Exported types ------------------------------------------------------------*/
|
||||||
/* Exported constants --------------------------------------------------------*/
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
/* Periodically, the state of the buffer "UserTxBuffer" is checked.
|
|
||||||
The period depends on USBD_CDC_POLLING_INTERVAL */
|
|
||||||
#define USBD_CDC_POLLING_INTERVAL 10 /* in ms. The max is 65 and the min is 1 */
|
|
||||||
|
|
||||||
extern TIM_HandleTypeDef TIM3_Handle;
|
extern TIM_HandleTypeDef TIM3_Handle;
|
||||||
extern const USBD_CDC_ItfTypeDef USBD_CDC_fops;
|
extern const USBD_CDC_ItfTypeDef USBD_CDC_fops;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue