stmhal: Add intensity method for blue LED.

As part of this, rejig the way TIM3 is initialised, since it's now
shared by USB CDC and the blue LED PWM.
This commit is contained in:
Damien George 2014-03-22 23:54:13 +00:00
parent 02fa035800
commit 908a670dfc
6 changed files with 112 additions and 99 deletions

View File

@ -1,10 +1,13 @@
#include <stdio.h>
#include <stm32f4xx_hal.h>
#include "usbd_cdc_msc.h"
#include "usbd_cdc_interface.h"
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#include "led.h"
#include "pin.h"
#include "build/pins.h"
@ -38,12 +41,43 @@ void led_init(void) {
GPIO_InitStructure.Pin = gLed[led]->pin_mask;
HAL_GPIO_Init(gLed[led]->gpio, &GPIO_InitStructure);
}
// LED4 (blue) is on PB4 which is TIM3_CH1
// we use PWM on this channel to fade the LED
// GPIO configuration
GPIO_InitStructure.Pin = GPIO_PIN_4;
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(GPIOB, &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);
//HAL_TIM_PWM_Start(&USBD_CDC_TIM3_Handle, TIM_CHANNEL_1);
}
void led_state(pyb_led_t led, int state) {
if (led < 1 || led > NUM_LEDS) {
return;
}
if (led == 4) {
if (state) {
TIM3->CCR1 = 0xffff;
} else {
TIM3->CCR1 = 0;
}
return;
}
const pin_obj_t *led_pin = gLed[led - 1];
//printf("led_state(%d,%d)\n", led, state);
if (state == 0) {
@ -73,6 +107,23 @@ void led_toggle(pyb_led_t led) {
}
}
int led_get_state(pyb_led_t led) {
if (led < 1 || led > NUM_LEDS) {
return 0;
}
const pin_obj_t *led_pin = gLed[led - 1];
GPIO_TypeDef *gpio = led_pin->gpio;
// TODO convert high/low to on/off depending on board
if (gpio->ODR & led_pin->pin_mask) {
// pin is high
return 1;
} else {
// pin is low
return 0;
}
}
void led_debug(int n, int delay) {
led_state(1, n & 1);
led_state(2, n & 2);
@ -112,25 +163,47 @@ mp_obj_t led_obj_toggle(mp_obj_t self_in) {
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle);
mp_obj_t led_obj_state(uint n_args, const mp_obj_t *args) {
pyb_led_obj_t *self = args[0];
if (n_args == 0) {
return MP_BOOL(led_get_state(self->led_id));
} else {
led_state(self->led_id, rt_is_true(args[1]));
return mp_const_none;
}
}
static const mp_method_t led_methods[] = {
mp_obj_t led_obj_intensity(mp_obj_t self_in, mp_obj_t intensity) {
pyb_led_obj_t *self = self_in;
if (self->led_id == 4) {
TIM3->CCR1 = mp_obj_get_int(intensity);
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(led_obj_state_obj, 1, 2, led_obj_state);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(led_obj_intensity_obj, led_obj_intensity);
STATIC const mp_method_t led_methods[] = {
{ "on", &led_obj_on_obj },
{ "off", &led_obj_off_obj },
{ "toggle", &led_obj_toggle_obj },
{ "state", &led_obj_state_obj },
{ "intensity", &led_obj_intensity_obj },
{ NULL, NULL },
};
static const mp_obj_type_t led_obj_type = {
STATIC const mp_obj_type_t led_obj_type = {
{ &mp_type_type },
.name = MP_QSTR_Led,
.print = led_obj_print,
.methods = led_methods,
};
static mp_obj_t pyb_Led(mp_obj_t led_id) {
STATIC mp_obj_t pyb_Led(mp_obj_t led_id) {
pyb_led_obj_t *o = m_new_obj(pyb_led_obj_t);
o->base.type = &led_obj_type;
o->led_id = mp_obj_get_int(led_id);

View File

@ -37,10 +37,10 @@
#include "lcd.h"
#include "accel.h"
#include "servo.h"
#include "pin.h"
#if 0
#include "timer.h"
#include "pybwlan.h"
#include "pin.h"
#endif
void SystemClock_Config(void);
@ -266,9 +266,7 @@ soft_reset:
#endif
#endif
#if 0
pin_map_init();
#endif
// add some functions to the builtin Python namespace
rt_store_name(MP_QSTR_help, rt_make_function_n(0, pyb_help));

View File

@ -5,16 +5,7 @@
* @version V1.0.1
* @date 26-February-2014
* @brief HAL MSP module.
*
@verbatim
===============================================================================
##### How to use this driver #####
===============================================================================
[..]
This file is generated automatically by MicroXplorer and eventually modified
by the user
@endverbatim
*
******************************************************************************
* @attention
*
@ -56,25 +47,7 @@
#include "obj.h"
#include "servo.h"
/** @addtogroup STM32F4xx_HAL_Driver
* @{
*/
/** @defgroup HAL_MSP
* @brief HAL MSP module.
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup HAL_MSP_Private_Functions
* @{
*/
TIM_HandleTypeDef TIM3_Handle;
/**
* @brief Initializes the Global MSP.
@ -83,9 +56,21 @@
*/
void HAL_MspInit(void) {
// set up the timer for USBD CDC
USBD_CDC_TIMx_CLK_ENABLE();
HAL_NVIC_SetPriority(USBD_CDC_TIMx_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(USBD_CDC_TIMx_IRQn);
__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 */
}
}
/**
@ -94,9 +79,9 @@ void HAL_MspInit(void) {
* @retval None
*/
void HAL_MspDeInit(void) {
// reset USBD CDC timer
USBD_CDC_TIMx_FORCE_RESET();
USBD_CDC_TIMx_RELEASE_RESET();
// reset TIM3 timer
__TIM3_FORCE_RESET();
__TIM3_RELEASE_RESET();
}
/**
@ -162,7 +147,7 @@ void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc)
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &USBD_CDC_TIM3_Handle) {
if (htim == &TIM3_Handle) {
USBD_CDC_HAL_TIM_PeriodElapsedCallback();
} else if (htim == &servo_TIM2_Handle) {
servo_timer_irq_callback();

View File

@ -357,8 +357,7 @@ void TIM2_IRQHandler(void) {
}
void TIM3_IRQHandler(void) {
// USBD CDC timer is TIM3
HAL_TIM_IRQHandler(&USBD_CDC_TIM3_Handle);
HAL_TIM_IRQHandler(&TIM3_Handle);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -65,8 +65,6 @@ static uint16_t UserTxBufPtrOut = 0; // increment this pointer modulo APP_TX_DAT
static int user_interrupt_char = VCP_CHAR_NONE;
static void *user_interrupt_data = NULL;
/* TIM handler declaration */
TIM_HandleTypeDef USBD_CDC_TIM3_Handle;
/* USB handler declaration */
extern USBD_HandleTypeDef hUSBDDevice;
@ -76,8 +74,6 @@ static int8_t CDC_Itf_DeInit (void);
static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length);
static int8_t CDC_Itf_Receive (uint8_t* pbuf, uint32_t *Len);
static void TIM_Config(void);
const USBD_CDC_ItfTypeDef USBD_CDC_fops = {
CDC_Itf_Init,
CDC_Itf_DeInit,
@ -125,21 +121,19 @@ static int8_t CDC_Itf_Init(void)
/* Transfer error in reception process */
Error_Handler();
}
#endif
/*##-3- Configure the TIM Base generation #################################*/
now done in HAL_MspInit
TIM_Config();
#endif
/*##-4- Start the TIM Base generation in interrupt mode ####################*/
/* Start Channel1 */
if(HAL_TIM_Base_Start_IT(&USBD_CDC_TIM3_Handle) != HAL_OK)
{
/* Starting Error */
}
/*##-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);
/*##-5- Set Application Buffers ############################################*/
USBD_CDC_SetTxBuffer(&hUSBDDevice, UserTxBuffer, 0);
USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer);
UserRxBufCur = 0;
UserRxBufLen = 0;
@ -147,7 +141,7 @@ static int8_t CDC_Itf_Init(void)
user_interrupt_char = VCP_CHAR_NONE;
user_interrupt_data = NULL;
return (USBD_OK);
return (USBD_OK);
}
/**
@ -378,29 +372,3 @@ int USBD_CDC_RxGet(void) {
}
return c;
}
/**
* @brief TIM_Config: Configure TIMx timer
* @param None.
* @retval None.
*/
static void TIM_Config(void)
{
/* Set TIMx instance */
USBD_CDC_TIM3_Handle.Instance = USBD_CDC_TIMx;
/* Initialize TIM3 peripheral as follow:
+ Period = 10000 - 1
+ Prescaler = ((SystemCoreClock/2)/10000) - 1
+ ClockDivision = 0
+ Counter direction = Up
*/
USBD_CDC_TIM3_Handle.Init.Period = (USBD_CDC_POLLING_INTERVAL*1000) - 1;
USBD_CDC_TIM3_Handle.Init.Prescaler = 84-1;
USBD_CDC_TIM3_Handle.Init.ClockDivision = 0;
USBD_CDC_TIM3_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
if(HAL_TIM_Base_Init(&USBD_CDC_TIM3_Handle) != HAL_OK)
{
/* Initialization Error */
}
}

View File

@ -33,21 +33,11 @@
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Definition for TIMx clock resources */
#define USBD_CDC_TIMx TIM3
#define USBD_CDC_TIMx_CLK_ENABLE __TIM3_CLK_ENABLE
#define USBD_CDC_TIMx_FORCE_RESET() __TIM3_FORCE_RESET()
#define USBD_CDC_TIMx_RELEASE_RESET() __TIM3_RELEASE_RESET()
/* Definition for TIMx's NVIC */
#define USBD_CDC_TIMx_IRQn TIM3_IRQn
//#define USBD_CDC_TIMx_IRQHandler TIM3_IRQHandler // this is hard coded in stm32f4xx_it.c
/* 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 USBD_CDC_TIM3_Handle;
extern TIM_HandleTypeDef TIM3_Handle;
extern const USBD_CDC_ItfTypeDef USBD_CDC_fops;
void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void);