Setting up TIM1 for WS2812

This commit is contained in:
Ben V. Brown
2021-05-02 17:42:41 +10:00
parent 1ad00aa8b2
commit 2e0279b36a
6 changed files with 468 additions and 458 deletions

View File

@@ -17,9 +17,7 @@ uint16_t totalPWM = 255;
const uint16_t powerPWM = 255;
history<uint16_t, PID_TIM_HZ> rawTempFilter = {{0}, 0, 0};
void resetWatchdog() {
HAL_IWDG_Refresh(&hiwdg);
}
void resetWatchdog() { HAL_IWDG_Refresh(&hiwdg); }
#ifdef TEMP_NTC
// Lookup table for the NTC
@@ -187,8 +185,7 @@ static const uint16_t NTCHandleLookup[] = {
29104, 20, //
29272, 10, //
};
const int NTCHandleLookupItems = sizeof(NTCHandleLookup)
/ (2 * sizeof(uint16_t));
const int NTCHandleLookupItems = sizeof(NTCHandleLookup) / (2 * sizeof(uint16_t));
#endif
// These are called by the HAL after the corresponding events from the system
@@ -196,20 +193,17 @@ const int NTCHandleLookupItems = sizeof(NTCHandleLookup)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
// Period has elapsed
if (htim->Instance == TIM1) {
if (htim->Instance == TIM4) {
// STM uses this for internal functions as a counter for timeouts
HAL_IncTick();
}
}
uint16_t getHandleTemperature() {
int32_t result = getADC(0);
return Utils::InterpolateLookupTable(NTCHandleLookup, NTCHandleLookupItems,
result);
return Utils::InterpolateLookupTable(NTCHandleLookup, NTCHandleLookupItems, result);
}
uint16_t getTipInstantTemperature() {
return getADC(2);
}
uint16_t getTipInstantTemperature() { return getADC(2); }
uint16_t getTipRawTemp(uint8_t refresh) {
if (refresh) {
@@ -327,25 +321,14 @@ void unstick_I2C() {
HAL_I2C_Init(&hi2c1);
}
uint8_t getButtonA() {
return HAL_GPIO_ReadPin(KEY_A_GPIO_Port, KEY_A_Pin) == GPIO_PIN_RESET ?
1 : 0;
}
uint8_t getButtonB() {
return HAL_GPIO_ReadPin(KEY_B_GPIO_Port, KEY_B_Pin) == GPIO_PIN_RESET ?
1 : 0;
}
uint8_t getButtonA() { return HAL_GPIO_ReadPin(KEY_A_GPIO_Port, KEY_A_Pin) == GPIO_PIN_RESET ? 1 : 0; }
uint8_t getButtonB() { return HAL_GPIO_ReadPin(KEY_B_GPIO_Port, KEY_B_Pin) == GPIO_PIN_RESET ? 1 : 0; }
void BSPInit(void) {
}
void BSPInit(void) {}
void reboot() {
NVIC_SystemReset();
}
void reboot() { NVIC_SystemReset(); }
void delay_ms(uint16_t count) {
HAL_Delay(count);
}
void delay_ms(uint16_t count) { HAL_Delay(count); }
void setPlatePullup(bool pullingUp) {
GPIO_InitTypeDef GPIO_InitStruct;
@@ -354,13 +337,11 @@ void setPlatePullup(bool pullingUp) {
GPIO_InitStruct.Pull = GPIO_NOPULL;
if (pullingUp) {
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_WritePin(PLATE_SENSOR_PULLUP_GPIO_Port,
PLATE_SENSOR_PULLUP_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(PLATE_SENSOR_PULLUP_GPIO_Port, PLATE_SENSOR_PULLUP_Pin, GPIO_PIN_SET);
} else {
// Hi-z
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_WritePin(PLATE_SENSOR_PULLUP_GPIO_Port,
PLATE_SENSOR_PULLUP_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(PLATE_SENSOR_PULLUP_GPIO_Port, PLATE_SENSOR_PULLUP_Pin, GPIO_PIN_RESET);
}
HAL_GPIO_Init(PLATE_SENSOR_PULLUP_GPIO_Port, &GPIO_InitStruct);
}
@@ -379,8 +360,7 @@ bool isTipDisconnected() {
bool tipDisconnected = getADC(2) > 4090;
// We have to handle here that this ^ will trip while measuring the gain resistor
if (xTaskGetTickCount() - lastMeas
< (TICKS_100MS * 2 + (TICKS_100MS / 2))) {
if (xTaskGetTickCount() - lastMeas < (TICKS_100MS * 2 + (TICKS_100MS / 2))) {
tipDisconnected = false;
}
@@ -408,19 +388,15 @@ bool isTipDisconnected() {
} else {
// We have taken reading one
uint16_t adcReadingPD1Cleared = getADC(3);
uint32_t a = ((int) adcReadingPD1Set
- (int) adcReadingPD1Cleared);
uint32_t a = ((int)adcReadingPD1Set - (int)adcReadingPD1Cleared);
a *= 10000;
uint32_t b = ((int) adcReadingPD1Cleared
+ (32768 - (int) adcReadingPD1Set));
uint32_t b = ((int)adcReadingPD1Cleared + (32768 - (int)adcReadingPD1Set));
if (b) {
tipSenseResistancex10Ohms = a / b;
} else {
tipSenseResistancex10Ohms = adcReadingPD1Set =
lastMeas = 0;
tipSenseResistancex10Ohms = adcReadingPD1Set = lastMeas = 0;
}
if (tipSenseResistancex10Ohms > 1100
|| tipSenseResistancex10Ohms < 900) {
if (tipSenseResistancex10Ohms > 1100 || tipSenseResistancex10Ohms < 900) {
tipSenseResistancex10Ohms = 0; // out of range
adcReadingPD1Set = 0;
lastMeas = 0;
@@ -434,5 +410,4 @@ bool isTipDisconnected() {
return tipDisconnected;
}
void setStatusLED(const enum StatusLED state) {
}
void setStatusLED(const enum StatusLED state) {}

View File

@@ -50,4 +50,7 @@
#define PLATE_SENSOR_GPIO_Port GPIOA
#define PLATE_SENSOR_ADC1_CHANNEL ADC_CHANNEL_5
#define PLATE_SENSOR_ADC2_CHANNEL ADC_CHANNEL_5
#define WS2812_Pin GPIO_PIN_3
#define WS2812_GPIO_Port GPIOA
#endif /* BSP_MINIWARE_PINS_H_ */

View File

@@ -16,6 +16,8 @@ DMA_HandleTypeDef hdma_i2c1_rx;
DMA_HandleTypeDef hdma_i2c1_tx;
IWDG_HandleTypeDef hiwdg;
TIM_HandleTypeDef htim1;
DMA_HandleTypeDef hdma_tim1_ch2;
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;
#define ADC_CHANNELS 4
@@ -29,6 +31,7 @@ static void MX_I2C1_Init(void);
static void MX_IWDG_Init(void);
static void MX_TIM3_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM1_Init(void);
static void MX_DMA_Init(void);
static void MX_GPIO_Init(void);
static void MX_ADC2_Init(void);
@@ -44,6 +47,7 @@ void Setup_HAL() {
MX_ADC2_Init();
MX_TIM3_Init();
MX_TIM2_Init();
MX_TIM1_Init();
MX_IWDG_Init();
HAL_ADC_Start(&hadc2);
HAL_ADCEx_MultiModeStart_DMA(&hadc1, ADCReadings,
@@ -218,6 +222,65 @@ static void MX_IWDG_Init(void) {
#endif
}
/* TIM1 init function */
void MX_TIM1_Init(void) {
/* USER CODE BEGIN TIM1_Init 0 */
/* USER CODE END TIM1_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
/* USER CODE BEGIN TIM1_Init 1 */
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 104;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK) {}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) {}
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) {}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) {}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) {}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) {}
/* USER CODE BEGIN TIM1_Init 2 */
/* USER CODE END TIM1_Init 2 */
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
/**TIM1 GPIO Configuration
PA9 ------> TIM1_CH2
*/
GPIO_InitStruct.Pin = WS2812_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(WS2812_GPIO_Port, &GPIO_InitStruct);
}
/* TIM3 init function */
static void MX_TIM3_Init(void) {
TIM_ClockConfigTypeDef sClockSourceConfig;
@@ -312,8 +375,11 @@ static void MX_DMA_Init(void) {
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 5, 0);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 10, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 6, 0); // DMA 1 ch3 is used from TIM CH2 for WS2812
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
/* DMA1_Channel6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);

View File

@@ -24,6 +24,8 @@ extern I2C_HandleTypeDef hi2c1;
extern IWDG_HandleTypeDef hiwdg;
extern TIM_HandleTypeDef htim1;
extern DMA_HandleTypeDef hdma_tim1_ch2;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim3;
void Setup_HAL();

View File

@@ -125,11 +125,22 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) {
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim_base) {
if (htim_base->Instance == TIM3) {
/* Peripheral clock enable */
if (htim_base->Instance == TIM1) {
__HAL_RCC_TIM1_CLK_ENABLE();
hdma_tim1_ch2.Instance = DMA1_Channel3;
hdma_tim1_ch2.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tim1_ch2.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim1_ch2.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim1_ch2.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_tim1_ch2.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_tim1_ch2.Init.Mode = DMA_CIRCULAR;
hdma_tim1_ch2.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_tim1_ch2) != HAL_OK) {}
__HAL_LINKDMA(htim_base, hdma[TIM_DMA_ID_CC2], hdma_tim1_ch2);
} else if (htim_base->Instance == TIM3) {
__HAL_RCC_TIM3_CLK_ENABLE();
} else if (htim_base->Instance == TIM2) {
/* Peripheral clock enable */
__HAL_RCC_TIM2_CLK_ENABLE();
}
}

View File

@@ -1,78 +1,42 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f1xx_hal_timebase_TIM.c
* @brief HAL time base based on the hardware TIM.
******************************************************************************
* This notice applies to any and all portions of this file
* that are not between comment pairs USER CODE BEGIN and
* USER CODE END. Other portions of this file, whether
* inserted by the user or by software development tools
* are owned by their respective copyright owners.
* @attention
*
* Copyright (c) 2017 STMicroelectronics International N.V.
* All rights reserved.
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted, provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific written permission.
* 4. This software, including modifications and/or derivative works of this
* software, must execute solely and exclusively on microcontroller or
* microprocessor devices manufactured by or for STMicroelectronics.
* 5. Redistribution and use of this software other than as permitted under
* this license is void and will automatically terminate your rights under
* this license.
*
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
* SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
#include "stm32f1xx_hal_tim.h"
/** @addtogroup STM32F7xx_HAL_Examples
* @{
*/
/** @addtogroup HAL_TimeBase
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim1;
uint32_t uwIncrementState = 0;
TIM_HandleTypeDef htim4;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief This function configures the TIM1 as a time base source.
* @brief This function configures the TIM4 as a time base source.
* The time source is configured to have 1ms time base with a dedicated
* Tick interrupt priority.
* @note This function is called automatically at the beginning of program after
* reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
* @param TickPriority: Tick interrupt priorty.
* @param TickPriority: Tick interrupt priority.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {
@@ -80,41 +44,38 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {
uint32_t uwTimclock = 0;
uint32_t uwPrescalerValue = 0;
uint32_t pFLatency;
/*Configure the TIM4 IRQ priority */
HAL_NVIC_SetPriority(TIM4_IRQn, TickPriority, 0);
/*Configure the TIM1 IRQ priority */
HAL_NVIC_SetPriority(TIM1_UP_IRQn, TickPriority, 0);
/* Enable the TIM1 global Interrupt */
HAL_NVIC_EnableIRQ(TIM1_UP_IRQn);
/* Enable TIM1 clock */
__HAL_RCC_TIM1_CLK_ENABLE();
/* Enable the TIM4 global Interrupt */
HAL_NVIC_EnableIRQ(TIM4_IRQn);
/* Enable TIM4 clock */
__HAL_RCC_TIM4_CLK_ENABLE();
/* Get clock configuration */
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
/* Compute TIM1 clock */
uwTimclock = HAL_RCC_GetPCLK2Freq();
/* Compute TIM4 clock */
uwTimclock = 2 * HAL_RCC_GetPCLK1Freq();
/* Compute the prescaler value to have TIM4 counter clock equal to 1MHz */
uwPrescalerValue = (uint32_t)((uwTimclock / 1000000U) - 1U);
/* Compute the prescaler value to have TIM1 counter clock equal to 1MHz */
uwPrescalerValue = (uint32_t)((uwTimclock / 1000000) - 1);
/* Initialize TIM1 */
htim1.Instance = TIM1;
/* Initialize TIM4 */
htim4.Instance = TIM4;
/* Initialize TIMx peripheral as follow:
+ Period = [(TIM1CLK/1000) - 1]. to have a (1/1000) s time base.
+ Period = [(TIM4CLK/1000) - 1]. to have a (1/1000) s time base.
+ Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
+ ClockDivision = 0
+ Counter direction = Up
*/
htim1.Init.Period = (1000000 / 1000) - 1;
htim1.Init.Prescaler = uwPrescalerValue;
htim1.Init.ClockDivision = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
if (HAL_TIM_Base_Init(&htim1) == HAL_OK) {
htim4.Init.Period = (1000000U / 1000U) - 1U;
htim4.Init.Prescaler = uwPrescalerValue;
htim4.Init.ClockDivision = 0;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
if (HAL_TIM_Base_Init(&htim4) == HAL_OK) {
/* Start the TIM time Base generation in interrupt mode */
return HAL_TIM_Base_Start_IT(&htim1);
return HAL_TIM_Base_Start_IT(&htim4);
}
/* Return function status */
@@ -123,32 +84,24 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {
/**
* @brief Suspend Tick increment.
* @note Disable the tick increment by disabling TIM1 update interrupt.
* @note Disable the tick increment by disabling TIM4 update interrupt.
* @param None
* @retval None
*/
void HAL_SuspendTick(void) {
/* Disable TIM1 update Interrupt */
__HAL_TIM_DISABLE_IT(&htim1, TIM_IT_UPDATE);
/* Disable TIM4 update Interrupt */
__HAL_TIM_DISABLE_IT(&htim4, TIM_IT_UPDATE);
}
/**
* @brief Resume Tick increment.
* @note Enable the tick increment by Enabling TIM1 update interrupt.
* @note Enable the tick increment by Enabling TIM4 update interrupt.
* @param None
* @retval None
*/
void HAL_ResumeTick(void) {
/* Enable TIM1 Update interrupt */
__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE);
/* Enable TIM4 Update interrupt */
__HAL_TIM_ENABLE_IT(&htim4, TIM_IT_UPDATE);
}
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/