stmhal: Make TIM3 available for use by the user.
TIM3 is no longer used by USB CDC for triggering outgoing data, so we can now make it available to the user. PWM fading on LED(4) is now gone, but will be reinstated in a new way.
This commit is contained in:
parent
d363133917
commit
ea89b80ff4
|
@ -82,7 +82,6 @@
|
|||
|
||||
// USB config
|
||||
#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9)
|
||||
#define MICROPY_HW_USE_ALT_IRQ_FOR_CDC (1)
|
||||
|
||||
// MMA accelerometer config
|
||||
#define MICROPY_HW_MMA_AVDD_PIN (pin_A10)
|
||||
|
|
64
stmhal/led.c
64
stmhal/led.c
|
@ -83,46 +83,12 @@ void led_init(void) {
|
|||
GPIO_InitStructure.Pin = led_pin->pin_mask;
|
||||
HAL_GPIO_Init(led_pin->gpio, &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
#if MICROPY_HW_LED4_PWM
|
||||
// LED4 (blue) is on PB4 which is TIM3_CH1
|
||||
// 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_InitStructure.Pin = MICROPY_HW_LED4.pin_mask;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF2_TIM3;
|
||||
HAL_GPIO_Init(MICROPY_HW_LED4.gpio, &GPIO_InitStructure);
|
||||
|
||||
// PWM mode configuration
|
||||
TIM_OC_InitTypeDef oc_init;
|
||||
oc_init.OCMode = TIM_OCMODE_PWM1;
|
||||
oc_init.Pulse = 0; // off
|
||||
oc_init.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
oc_init.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
HAL_TIM_PWM_ConfigChannel(&TIM3_Handle, &oc_init, TIM_CHANNEL_1);
|
||||
|
||||
// start PWM
|
||||
TIM_CCxChannelCmd(TIM3, TIM_CHANNEL_1, TIM_CCx_ENABLE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void led_state(pyb_led_t led, int state) {
|
||||
if (led < 1 || led > NUM_LEDS) {
|
||||
return;
|
||||
}
|
||||
if (MICROPY_HW_LED4_PWM && led == 4) {
|
||||
if (state) {
|
||||
TIM3->CCR1 = 0xffff;
|
||||
} else {
|
||||
TIM3->CCR1 = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin;
|
||||
//printf("led_state(%d,%d)\n", led, state);
|
||||
if (state == 0) {
|
||||
|
@ -139,15 +105,6 @@ void led_toggle(pyb_led_t led) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (MICROPY_HW_LED4_PWM && led == 4) {
|
||||
if (TIM3->CCR1 == 0) {
|
||||
TIM3->CCR1 = 0xffff;
|
||||
} else {
|
||||
TIM3->CCR1 = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// toggle the output data register to toggle the LED state
|
||||
const pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin;
|
||||
led_pin->gpio->ODR ^= led_pin->pin_mask;
|
||||
|
@ -158,14 +115,6 @@ int led_get_intensity(pyb_led_t led) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (MICROPY_HW_LED4_PWM && led == 4) {
|
||||
mp_uint_t i = (TIM3->CCR1 * 255 + (USBD_CDC_POLLING_INTERVAL*1000) - 2) / ((USBD_CDC_POLLING_INTERVAL*1000) - 1);
|
||||
if (i > 255) {
|
||||
i = 255;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
const pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin;
|
||||
GPIO_TypeDef *gpio = led_pin->gpio;
|
||||
|
||||
|
@ -180,19 +129,6 @@ int led_get_intensity(pyb_led_t led) {
|
|||
}
|
||||
|
||||
void led_set_intensity(pyb_led_t led, mp_int_t intensity) {
|
||||
if (MICROPY_HW_LED4_PWM && led == 4) {
|
||||
// set intensity using PWM pulse width
|
||||
if (intensity < 0) {
|
||||
intensity = 0;
|
||||
} else if (intensity >= 255) {
|
||||
intensity = 0xffff;
|
||||
} else {
|
||||
intensity = intensity * ((USBD_CDC_POLLING_INTERVAL*1000) - 1) / 255;
|
||||
}
|
||||
TIM3->CCR1 = intensity;
|
||||
return;
|
||||
}
|
||||
|
||||
// intensity not supported for this LED; just turn it on/off
|
||||
led_state(led, intensity > 0);
|
||||
}
|
||||
|
|
|
@ -395,12 +395,6 @@ int main(void) {
|
|||
|
||||
// basic sub-system init
|
||||
pendsv_init();
|
||||
#if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
|
||||
HAL_NVIC_SetPriority(PVD_IRQn, 6, 0); // same priority as USB
|
||||
HAL_NVIC_EnableIRQ(PVD_IRQn);
|
||||
#else
|
||||
timer_tim3_init();
|
||||
#endif
|
||||
led_init();
|
||||
#if MICROPY_HW_HAS_SWITCH
|
||||
switch_init0();
|
||||
|
|
|
@ -253,7 +253,7 @@ STATIC mp_obj_t machine_freq(mp_uint_t n_args, const mp_obj_t *args) {
|
|||
//printf("%lu %lu %lu %lu %lu\n", sysclk_source, m, n, p, q);
|
||||
|
||||
// let the USB CDC have a chance to process before we change the clock
|
||||
HAL_Delay(USBD_CDC_POLLING_INTERVAL + 2);
|
||||
HAL_Delay(5);
|
||||
|
||||
// desired system clock source is in sysclk_source
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||||
|
@ -316,9 +316,6 @@ STATIC mp_obj_t machine_freq(mp_uint_t n_args, const mp_obj_t *args) {
|
|||
}
|
||||
}
|
||||
|
||||
// re-init TIM3 for USB CDC rate
|
||||
timer_tim3_init();
|
||||
|
||||
#if defined(MICROPY_HW_CLK_LAST_FREQ) && MICROPY_HW_CLK_LAST_FREQ
|
||||
#if defined(MCU_SERIES_F7)
|
||||
#define FREQ_BKP BKP31R
|
||||
|
|
|
@ -278,12 +278,6 @@ void SysTick_Handler(void) {
|
|||
// be generalised in the future then a dispatch table can be used as
|
||||
// follows: ((void(*)(void))(systick_dispatch[uwTick & 0xf]))();
|
||||
|
||||
#if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
|
||||
if (((uwTick) & 7) == 4) { // every 8ms
|
||||
NVIC->STIR = PVD_IRQn;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (STORAGE_IDLE_TICK(uwTick)) {
|
||||
NVIC->STIR = FLASH_IRQn;
|
||||
}
|
||||
|
@ -479,8 +473,6 @@ void EXTI15_10_IRQHandler(void) {
|
|||
|
||||
void PVD_IRQHandler(void) {
|
||||
IRQ_ENTER(PVD_IRQn);
|
||||
#if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
|
||||
#endif
|
||||
Handle_EXTI_Irq(EXTI_PVD_OUTPUT);
|
||||
IRQ_EXIT(PVD_IRQn);
|
||||
}
|
||||
|
@ -539,11 +531,7 @@ void TIM2_IRQHandler(void) {
|
|||
|
||||
void TIM3_IRQHandler(void) {
|
||||
IRQ_ENTER(TIM3_IRQn);
|
||||
#if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
|
||||
timer_irq_handler(3);
|
||||
#else
|
||||
HAL_TIM_IRQHandler(&TIM3_Handle);
|
||||
#endif
|
||||
IRQ_EXIT(TIM3_IRQn);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
/// tim.callback(lambda t: ...) # set callback for update interrupt (t=tim instance)
|
||||
/// tim.callback(None) # clear callback
|
||||
///
|
||||
/// *Note:* Timer 3 is reserved for internal use. Timer 5 controls
|
||||
/// *Note:* Timer 3 is used for fading the blue LED. Timer 5 controls
|
||||
/// the servo driver, and Timer 6 is used for timed ADC/DAC reading/writing.
|
||||
/// It is recommended to use the other timers in your programs.
|
||||
|
||||
|
@ -76,8 +76,6 @@
|
|||
// the interrupts to be dispatched, so they are all collected here.
|
||||
//
|
||||
// TIM3:
|
||||
// - flash storage controller, to flush the cache
|
||||
// - USB CDC interface, interval, to check for new data
|
||||
// - LED 4, PWM to set the LED intensity
|
||||
//
|
||||
// TIM5:
|
||||
|
@ -144,7 +142,6 @@ typedef struct _pyb_timer_obj_t {
|
|||
#define TIMER_CNT_MASK(self) ((self)->is_32bit ? 0xffffffff : 0xffff)
|
||||
#define TIMER_CHANNEL(self) ((((self)->channel) - 1) << 2)
|
||||
|
||||
TIM_HandleTypeDef TIM3_Handle;
|
||||
TIM_HandleTypeDef TIM5_Handle;
|
||||
TIM_HandleTypeDef TIM6_Handle;
|
||||
|
||||
|
@ -171,34 +168,6 @@ void timer_deinit(void) {
|
|||
}
|
||||
}
|
||||
|
||||
// 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 fires every USBD_CDC_POLLING_INTERVAL ms
|
||||
TIM3_Handle.Init.Prescaler = timer_get_source_freq(3) / 1000000 - 1; // TIM3 runs at 1MHz
|
||||
TIM3_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
TIM3_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
HAL_TIM_Base_Init(&TIM3_Handle);
|
||||
|
||||
HAL_NVIC_SetPriority(TIM3_IRQn, IRQ_PRI_TIM3, IRQ_SUBPRI_TIM3);
|
||||
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
|
||||
// This function inits but does not start the timer
|
||||
void timer_tim5_init(void) {
|
||||
|
@ -250,10 +219,6 @@ TIM_HandleTypeDef *timer_tim6_init(uint freq) {
|
|||
|
||||
// Interrupt dispatch
|
||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
||||
#if !defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
|
||||
if (htim == &TIM3_Handle) {
|
||||
} else
|
||||
#endif
|
||||
if (htim == &TIM5_Handle) {
|
||||
servo_timer_irq_callback();
|
||||
}
|
||||
|
@ -655,11 +620,7 @@ STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, mp_uint_t n_args,
|
|||
switch (tim->tim_id) {
|
||||
case 1: tim->tim.Instance = TIM1; tim->irqn = TIM1_UP_TIM10_IRQn; break;
|
||||
case 2: tim->tim.Instance = TIM2; tim->irqn = TIM2_IRQn; tim->is_32bit = true; break;
|
||||
#if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
|
||||
case 3: tim->tim.Instance = TIM3; tim->irqn = TIM3_IRQn; break;
|
||||
#else
|
||||
case 3: nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Timer 3 is for internal use only")); // TIM3 used for low-level stuff; go via regs if necessary
|
||||
#endif
|
||||
case 4: tim->tim.Instance = TIM4; tim->irqn = TIM4_IRQn; break;
|
||||
case 5: tim->tim.Instance = TIM5; tim->irqn = TIM5_IRQn; tim->is_32bit = true; break;
|
||||
#if defined(TIM6)
|
||||
|
|
|
@ -24,18 +24,11 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// 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;
|
||||
|
||||
extern const mp_obj_type_t pyb_timer_type;
|
||||
|
||||
void timer_init0(void);
|
||||
void timer_tim3_init(void);
|
||||
void timer_tim5_init(void);
|
||||
TIM_HandleTypeDef *timer_tim6_init(uint freq);
|
||||
|
||||
|
|
|
@ -140,10 +140,6 @@ static int8_t CDC_Itf_Init(void)
|
|||
TIM_Config();
|
||||
#endif
|
||||
|
||||
/*##-4- Start the TIM Base generation in interrupt mode ####################*/
|
||||
/* Start Channel1 */
|
||||
__HAL_TIM_ENABLE_IT(&TIM3_Handle, TIM_IT_UPDATE);
|
||||
|
||||
/*##-5- Set Application Buffers ############################################*/
|
||||
USBD_CDC_SetTxBuffer(&hUSBDDevice, UserTxBuffer, 0);
|
||||
USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer);
|
||||
|
|
Loading…
Reference in New Issue