Skip to content

Commit 908a670

Browse files
committed
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.
1 parent 02fa035 commit 908a670

6 files changed

Lines changed: 112 additions & 99 deletions

File tree

stmhal/led.c

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
#include <stdio.h>
22
#include <stm32f4xx_hal.h>
3+
#include "usbd_cdc_msc.h"
4+
#include "usbd_cdc_interface.h"
35

46
#include "misc.h"
57
#include "mpconfig.h"
68
#include "qstr.h"
79
#include "obj.h"
10+
#include "runtime.h"
811
#include "led.h"
912
#include "pin.h"
1013
#include "build/pins.h"
@@ -38,12 +41,43 @@ void led_init(void) {
3841
GPIO_InitStructure.Pin = gLed[led]->pin_mask;
3942
HAL_GPIO_Init(gLed[led]->gpio, &GPIO_InitStructure);
4043
}
44+
45+
// LED4 (blue) is on PB4 which is TIM3_CH1
46+
// we use PWM on this channel to fade the LED
47+
48+
// GPIO configuration
49+
GPIO_InitStructure.Pin = GPIO_PIN_4;
50+
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
51+
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
52+
GPIO_InitStructure.Pull = GPIO_NOPULL;
53+
GPIO_InitStructure.Alternate = GPIO_AF2_TIM3;
54+
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
55+
56+
// PWM mode configuration
57+
TIM_OC_InitTypeDef oc_init;
58+
oc_init.OCMode = TIM_OCMODE_PWM1;
59+
oc_init.Pulse = 0; // off
60+
oc_init.OCPolarity = TIM_OCPOLARITY_HIGH;
61+
oc_init.OCFastMode = TIM_OCFAST_DISABLE;
62+
HAL_TIM_PWM_ConfigChannel(&TIM3_Handle, &oc_init, TIM_CHANNEL_1);
63+
64+
// start PWM
65+
TIM_CCxChannelCmd(TIM3, TIM_CHANNEL_1, TIM_CCx_ENABLE);
66+
//HAL_TIM_PWM_Start(&USBD_CDC_TIM3_Handle, TIM_CHANNEL_1);
4167
}
4268

4369
void led_state(pyb_led_t led, int state) {
4470
if (led < 1 || led > NUM_LEDS) {
4571
return;
4672
}
73+
if (led == 4) {
74+
if (state) {
75+
TIM3->CCR1 = 0xffff;
76+
} else {
77+
TIM3->CCR1 = 0;
78+
}
79+
return;
80+
}
4781
const pin_obj_t *led_pin = gLed[led - 1];
4882
//printf("led_state(%d,%d)\n", led, state);
4983
if (state == 0) {
@@ -73,6 +107,23 @@ void led_toggle(pyb_led_t led) {
73107
}
74108
}
75109

110+
int led_get_state(pyb_led_t led) {
111+
if (led < 1 || led > NUM_LEDS) {
112+
return 0;
113+
}
114+
const pin_obj_t *led_pin = gLed[led - 1];
115+
GPIO_TypeDef *gpio = led_pin->gpio;
116+
117+
// TODO convert high/low to on/off depending on board
118+
if (gpio->ODR & led_pin->pin_mask) {
119+
// pin is high
120+
return 1;
121+
} else {
122+
// pin is low
123+
return 0;
124+
}
125+
}
126+
76127
void led_debug(int n, int delay) {
77128
led_state(1, n & 1);
78129
led_state(2, n & 2);
@@ -112,25 +163,47 @@ mp_obj_t led_obj_toggle(mp_obj_t self_in) {
112163
return mp_const_none;
113164
}
114165

115-
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
116-
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
117-
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle);
166+
mp_obj_t led_obj_state(uint n_args, const mp_obj_t *args) {
167+
pyb_led_obj_t *self = args[0];
168+
if (n_args == 0) {
169+
return MP_BOOL(led_get_state(self->led_id));
170+
} else {
171+
led_state(self->led_id, rt_is_true(args[1]));
172+
return mp_const_none;
173+
}
174+
}
175+
176+
mp_obj_t led_obj_intensity(mp_obj_t self_in, mp_obj_t intensity) {
177+
pyb_led_obj_t *self = self_in;
178+
if (self->led_id == 4) {
179+
TIM3->CCR1 = mp_obj_get_int(intensity);
180+
}
181+
return mp_const_none;
182+
}
183+
184+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
185+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
186+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle);
187+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(led_obj_state_obj, 1, 2, led_obj_state);
188+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(led_obj_intensity_obj, led_obj_intensity);
118189

119-
static const mp_method_t led_methods[] = {
190+
STATIC const mp_method_t led_methods[] = {
120191
{ "on", &led_obj_on_obj },
121192
{ "off", &led_obj_off_obj },
122193
{ "toggle", &led_obj_toggle_obj },
194+
{ "state", &led_obj_state_obj },
195+
{ "intensity", &led_obj_intensity_obj },
123196
{ NULL, NULL },
124197
};
125198

126-
static const mp_obj_type_t led_obj_type = {
199+
STATIC const mp_obj_type_t led_obj_type = {
127200
{ &mp_type_type },
128201
.name = MP_QSTR_Led,
129202
.print = led_obj_print,
130203
.methods = led_methods,
131204
};
132205

133-
static mp_obj_t pyb_Led(mp_obj_t led_id) {
206+
STATIC mp_obj_t pyb_Led(mp_obj_t led_id) {
134207
pyb_led_obj_t *o = m_new_obj(pyb_led_obj_t);
135208
o->base.type = &led_obj_type;
136209
o->led_id = mp_obj_get_int(led_id);

stmhal/main.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@
3737
#include "lcd.h"
3838
#include "accel.h"
3939
#include "servo.h"
40+
#include "pin.h"
4041
#if 0
4142
#include "timer.h"
4243
#include "pybwlan.h"
43-
#include "pin.h"
4444
#endif
4545

4646
void SystemClock_Config(void);
@@ -266,9 +266,7 @@ int main(void) {
266266
#endif
267267
#endif
268268

269-
#if 0
270269
pin_map_init();
271-
#endif
272270

273271
// add some functions to the builtin Python namespace
274272
rt_store_name(MP_QSTR_help, rt_make_function_n(0, pyb_help));

stmhal/stm32f4xx_hal_msp.c

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,7 @@
55
* @version V1.0.1
66
* @date 26-February-2014
77
* @brief HAL MSP module.
8-
*
9-
@verbatim
10-
===============================================================================
11-
##### How to use this driver #####
12-
===============================================================================
13-
[..]
14-
This file is generated automatically by MicroXplorer and eventually modified
15-
by the user
16-
17-
@endverbatim
8+
*
189
******************************************************************************
1910
* @attention
2011
*
@@ -56,25 +47,7 @@
5647
#include "obj.h"
5748
#include "servo.h"
5849

59-
/** @addtogroup STM32F4xx_HAL_Driver
60-
* @{
61-
*/
62-
63-
/** @defgroup HAL_MSP
64-
* @brief HAL MSP module.
65-
* @{
66-
*/
67-
68-
/* Private typedef -----------------------------------------------------------*/
69-
/* Private define ------------------------------------------------------------*/
70-
/* Private macro -------------------------------------------------------------*/
71-
/* Private variables ---------------------------------------------------------*/
72-
/* Private function prototypes -----------------------------------------------*/
73-
/* Private functions ---------------------------------------------------------*/
74-
75-
/** @defgroup HAL_MSP_Private_Functions
76-
* @{
77-
*/
50+
TIM_HandleTypeDef TIM3_Handle;
7851

7952
/**
8053
* @brief Initializes the Global MSP.
@@ -83,9 +56,21 @@
8356
*/
8457
void HAL_MspInit(void) {
8558
// set up the timer for USBD CDC
86-
USBD_CDC_TIMx_CLK_ENABLE();
87-
HAL_NVIC_SetPriority(USBD_CDC_TIMx_IRQn, 6, 0);
88-
HAL_NVIC_EnableIRQ(USBD_CDC_TIMx_IRQn);
59+
__TIM3_CLK_ENABLE();
60+
61+
TIM3_Handle.Instance = TIM3;
62+
TIM3_Handle.Init.Period = (USBD_CDC_POLLING_INTERVAL*1000) - 1;
63+
TIM3_Handle.Init.Prescaler = 84-1;
64+
TIM3_Handle.Init.ClockDivision = 0;
65+
TIM3_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
66+
HAL_TIM_Base_Init(&TIM3_Handle);
67+
68+
HAL_NVIC_SetPriority(TIM3_IRQn, 6, 0);
69+
HAL_NVIC_EnableIRQ(TIM3_IRQn);
70+
71+
if (HAL_TIM_Base_Start(&TIM3_Handle) != HAL_OK) {
72+
/* Starting Error */
73+
}
8974
}
9075

9176
/**
@@ -94,9 +79,9 @@ void HAL_MspInit(void) {
9479
* @retval None
9580
*/
9681
void HAL_MspDeInit(void) {
97-
// reset USBD CDC timer
98-
USBD_CDC_TIMx_FORCE_RESET();
99-
USBD_CDC_TIMx_RELEASE_RESET();
82+
// reset TIM3 timer
83+
__TIM3_FORCE_RESET();
84+
__TIM3_RELEASE_RESET();
10085
}
10186

10287
/**
@@ -162,7 +147,7 @@ void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc)
162147
}
163148

164149
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
165-
if (htim == &USBD_CDC_TIM3_Handle) {
150+
if (htim == &TIM3_Handle) {
166151
USBD_CDC_HAL_TIM_PeriodElapsedCallback();
167152
} else if (htim == &servo_TIM2_Handle) {
168153
servo_timer_irq_callback();

stmhal/stm32f4xx_it.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,7 @@ void TIM2_IRQHandler(void) {
357357
}
358358

359359
void TIM3_IRQHandler(void) {
360-
// USBD CDC timer is TIM3
361-
HAL_TIM_IRQHandler(&USBD_CDC_TIM3_Handle);
360+
HAL_TIM_IRQHandler(&TIM3_Handle);
362361
}
363362

364363
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

stmhal/usbd_cdc_interface.c

Lines changed: 9 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ static uint16_t UserTxBufPtrOut = 0; // increment this pointer modulo APP_TX_DAT
6565
static int user_interrupt_char = VCP_CHAR_NONE;
6666
static void *user_interrupt_data = NULL;
6767

68-
/* TIM handler declaration */
69-
TIM_HandleTypeDef USBD_CDC_TIM3_Handle;
7068
/* USB handler declaration */
7169
extern USBD_HandleTypeDef hUSBDDevice;
7270

@@ -76,8 +74,6 @@ static int8_t CDC_Itf_DeInit (void);
7674
static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length);
7775
static int8_t CDC_Itf_Receive (uint8_t* pbuf, uint32_t *Len);
7876

79-
static void TIM_Config(void);
80-
8177
const USBD_CDC_ItfTypeDef USBD_CDC_fops = {
8278
CDC_Itf_Init,
8379
CDC_Itf_DeInit,
@@ -125,29 +121,27 @@ static int8_t CDC_Itf_Init(void)
125121
/* Transfer error in reception process */
126122
Error_Handler();
127123
}
128-
#endif
129124

130125
/*##-3- Configure the TIM Base generation #################################*/
126+
now done in HAL_MspInit
131127
TIM_Config();
128+
#endif
132129

133-
/*##-4- Start the TIM Base generation in interrupt mode ####################*/
134-
/* Start Channel1 */
135-
if(HAL_TIM_Base_Start_IT(&USBD_CDC_TIM3_Handle) != HAL_OK)
136-
{
137-
/* Starting Error */
138-
}
130+
/*##-4- Start the TIM Base generation in interrupt mode ####################*/
131+
/* Start Channel1 */
132+
__HAL_TIM_ENABLE_IT(&TIM3_Handle, TIM_IT_UPDATE);
139133

140-
/*##-5- Set Application Buffers ############################################*/
141-
USBD_CDC_SetTxBuffer(&hUSBDDevice, UserTxBuffer, 0);
142-
USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer);
134+
/*##-5- Set Application Buffers ############################################*/
135+
USBD_CDC_SetTxBuffer(&hUSBDDevice, UserTxBuffer, 0);
136+
USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer);
143137

144138
UserRxBufCur = 0;
145139
UserRxBufLen = 0;
146140

147141
user_interrupt_char = VCP_CHAR_NONE;
148142
user_interrupt_data = NULL;
149143

150-
return (USBD_OK);
144+
return (USBD_OK);
151145
}
152146

153147
/**
@@ -378,29 +372,3 @@ int USBD_CDC_RxGet(void) {
378372
}
379373
return c;
380374
}
381-
382-
/**
383-
* @brief TIM_Config: Configure TIMx timer
384-
* @param None.
385-
* @retval None.
386-
*/
387-
static void TIM_Config(void)
388-
{
389-
/* Set TIMx instance */
390-
USBD_CDC_TIM3_Handle.Instance = USBD_CDC_TIMx;
391-
392-
/* Initialize TIM3 peripheral as follow:
393-
+ Period = 10000 - 1
394-
+ Prescaler = ((SystemCoreClock/2)/10000) - 1
395-
+ ClockDivision = 0
396-
+ Counter direction = Up
397-
*/
398-
USBD_CDC_TIM3_Handle.Init.Period = (USBD_CDC_POLLING_INTERVAL*1000) - 1;
399-
USBD_CDC_TIM3_Handle.Init.Prescaler = 84-1;
400-
USBD_CDC_TIM3_Handle.Init.ClockDivision = 0;
401-
USBD_CDC_TIM3_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
402-
if(HAL_TIM_Base_Init(&USBD_CDC_TIM3_Handle) != HAL_OK)
403-
{
404-
/* Initialization Error */
405-
}
406-
}

stmhal/usbd_cdc_interface.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,11 @@
3333
/* Exported types ------------------------------------------------------------*/
3434
/* Exported constants --------------------------------------------------------*/
3535

36-
/* Definition for TIMx clock resources */
37-
#define USBD_CDC_TIMx TIM3
38-
#define USBD_CDC_TIMx_CLK_ENABLE __TIM3_CLK_ENABLE
39-
#define USBD_CDC_TIMx_FORCE_RESET() __TIM3_FORCE_RESET()
40-
#define USBD_CDC_TIMx_RELEASE_RESET() __TIM3_RELEASE_RESET()
41-
42-
/* Definition for TIMx's NVIC */
43-
#define USBD_CDC_TIMx_IRQn TIM3_IRQn
44-
//#define USBD_CDC_TIMx_IRQHandler TIM3_IRQHandler // this is hard coded in stm32f4xx_it.c
45-
4636
/* Periodically, the state of the buffer "UserTxBuffer" is checked.
4737
The period depends on USBD_CDC_POLLING_INTERVAL */
4838
#define USBD_CDC_POLLING_INTERVAL 10 /* in ms. The max is 65 and the min is 1 */
4939

50-
extern TIM_HandleTypeDef USBD_CDC_TIM3_Handle;
40+
extern TIM_HandleTypeDef TIM3_Handle;
5141
extern const USBD_CDC_ItfTypeDef USBD_CDC_fops;
5242

5343
void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void);

0 commit comments

Comments
 (0)