Commit ea89b80f authored by Damien George's avatar Damien George
Browse files

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.
parent d3631339
......@@ -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)
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment