Input capture works. off by *2
This commit is contained in:
		@ -61,6 +61,7 @@ void FDCAN1_IT0_IRQHandler(void);
 | 
				
			|||||||
void FDCAN2_IT0_IRQHandler(void);
 | 
					void FDCAN2_IT0_IRQHandler(void);
 | 
				
			||||||
void FDCAN1_IT1_IRQHandler(void);
 | 
					void FDCAN1_IT1_IRQHandler(void);
 | 
				
			||||||
void FDCAN2_IT1_IRQHandler(void);
 | 
					void FDCAN2_IT1_IRQHandler(void);
 | 
				
			||||||
 | 
					void TIM8_CC_IRQHandler(void);
 | 
				
			||||||
/* USER CODE BEGIN EFP */
 | 
					/* USER CODE BEGIN EFP */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* USER CODE END EFP */
 | 
					/* USER CODE END EFP */
 | 
				
			||||||
 | 
				
			|||||||
@ -58,6 +58,8 @@ static uint8_t  dio_values[NUM_DIO_PINS];
 | 
				
			|||||||
TIM_HandleTypeDef* PWM_TIM_MAP[3] = {&htim1, &htim4, &htim3};
 | 
					TIM_HandleTypeDef* PWM_TIM_MAP[3] = {&htim1, &htim4, &htim3};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint8_t  pwm_ch_active[8];
 | 
					static uint8_t  pwm_ch_active[8];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint16_t wss_flanks[2];
 | 
				
			||||||
/* USER CODE END PV */
 | 
					/* USER CODE END PV */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Private function prototypes -----------------------------------------------*/
 | 
					/* Private function prototypes -----------------------------------------------*/
 | 
				
			||||||
@ -164,6 +166,10 @@ int main(void)
 | 
				
			|||||||
  // Init all channels as stopped
 | 
					  // Init all channels as stopped
 | 
				
			||||||
  memset(pwm_ch_active, 0, 8);
 | 
					  memset(pwm_ch_active, 0, 8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Start input capture for WSS
 | 
				
			||||||
 | 
					  HAL_TIM_IC_Start_IT(&htim8, TIM_CHANNEL_1);
 | 
				
			||||||
 | 
					  HAL_TIM_IC_Start_IT(&htim8, TIM_CHANNEL_2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* USER CODE END 2 */
 | 
					  /* USER CODE END 2 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Infinite loop */
 | 
					  /* Infinite loop */
 | 
				
			||||||
@ -207,7 +213,8 @@ int main(void)
 | 
				
			|||||||
              break;
 | 
					              break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            case FIN:
 | 
					            case FIN:
 | 
				
			||||||
              /* NYI */
 | 
					              value = wss_flanks[signal->channel];
 | 
				
			||||||
 | 
					              wss_flanks[signal->channel] = 0;
 | 
				
			||||||
              break;
 | 
					              break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
@ -319,6 +326,45 @@ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Input capture timing calculations:
 | 
				
			||||||
 | 
					 * wheel speed = 8000 rpm * (11/48) = 30.55 rot/s
 | 
				
			||||||
 | 
					 * if both flanks then 64 flanks per rot = 1956 flanks/s
 | 
				
			||||||
 | 
					 * That's ~500µs per flank or ~1ms per notch
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * TIM8 trigger prescaled = 96MHz/64 = 3MHz
 | 
				
			||||||
 | 
					 * Max Filter is 15 samples, at 666.666ns per sample
 | 
				
			||||||
 | 
					 * that's 10µs of filtering (flanks that are unstable
 | 
				
			||||||
 | 
					 * for this long will not trigger a capture interrupt)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * If we want to do further filtering, we can either
 | 
				
			||||||
 | 
					 * increase the prescaler and decrease the counter
 | 
				
			||||||
 | 
					 * period or do it in software using
 | 
				
			||||||
 | 
					 * HAL_TIM_ReadCapturedValue(&htim8, TIM_CHANNEL_X);
 | 
				
			||||||
 | 
					 * to measure the time between events.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (htim != &htim8 || htim->Channel < 1 || htim->Channel > 2)
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * Channels go 1,2,4,8... so we count the trailing zeros to get the index.
 | 
				
			||||||
 | 
					   * For this, we could use the nifty CTZ instruction, which gives us exactly that.
 | 
				
			||||||
 | 
					   * BUT according to godbolt we save 2 instructions by using subtraction,
 | 
				
			||||||
 | 
					   * which we can only do because we only use the first two channels.
 | 
				
			||||||
 | 
					   * Why 2 instructions? well, one because -1 can be done in the immediate when
 | 
				
			||||||
 | 
					   * writing to memory. Another one because ARMv7 32bit doesn't have CTZ but only
 | 
				
			||||||
 | 
					   * CLZ, so it must do RBIT before to reverse the result.
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * CAREFUL: When using more than 2 channels, you MUST use CTZ instead.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  wss_flanks[htim->Channel-1]++;
 | 
				
			||||||
 | 
					  //wss_flanks[__builtin_ctz(htim->Channel)]++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SetCCR(TIM_TypeDef* Instance, unsigned int ch, uint8_t dc) {
 | 
					void SetCCR(TIM_TypeDef* Instance, unsigned int ch, uint8_t dc) {
 | 
				
			||||||
  (&(Instance->CCR1))[ch] = dc;
 | 
					  (&(Instance->CCR1))[ch] = dc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -59,6 +59,7 @@ extern DMA_HandleTypeDef hdma_adc1;
 | 
				
			|||||||
extern ADC_HandleTypeDef hadc1;
 | 
					extern ADC_HandleTypeDef hadc1;
 | 
				
			||||||
extern FDCAN_HandleTypeDef hfdcan1;
 | 
					extern FDCAN_HandleTypeDef hfdcan1;
 | 
				
			||||||
extern FDCAN_HandleTypeDef hfdcan2;
 | 
					extern FDCAN_HandleTypeDef hfdcan2;
 | 
				
			||||||
 | 
					extern TIM_HandleTypeDef htim8;
 | 
				
			||||||
/* USER CODE BEGIN EV */
 | 
					/* USER CODE BEGIN EV */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* USER CODE END EV */
 | 
					/* USER CODE END EV */
 | 
				
			||||||
@ -285,6 +286,20 @@ void FDCAN2_IT1_IRQHandler(void)
 | 
				
			|||||||
  /* USER CODE END FDCAN2_IT1_IRQn 1 */
 | 
					  /* USER CODE END FDCAN2_IT1_IRQn 1 */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					  * @brief This function handles TIM8 capture compare interrupt.
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					void TIM8_CC_IRQHandler(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  /* USER CODE BEGIN TIM8_CC_IRQn 0 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* USER CODE END TIM8_CC_IRQn 0 */
 | 
				
			||||||
 | 
					  HAL_TIM_IRQHandler(&htim8);
 | 
				
			||||||
 | 
					  /* USER CODE BEGIN TIM8_CC_IRQn 1 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* USER CODE END TIM8_CC_IRQn 1 */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* USER CODE BEGIN 1 */
 | 
					/* USER CODE BEGIN 1 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* USER CODE END 1 */
 | 
					/* USER CODE END 1 */
 | 
				
			||||||
 | 
				
			|||||||
@ -251,9 +251,9 @@ void MX_TIM8_Init(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* USER CODE END TIM8_Init 1 */
 | 
					  /* USER CODE END TIM8_Init 1 */
 | 
				
			||||||
  htim8.Instance = TIM8;
 | 
					  htim8.Instance = TIM8;
 | 
				
			||||||
  htim8.Init.Prescaler = 0;
 | 
					  htim8.Init.Prescaler = 63;
 | 
				
			||||||
  htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
 | 
					  htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
 | 
				
			||||||
  htim8.Init.Period = 65535;
 | 
					  htim8.Init.Period = 14999;
 | 
				
			||||||
  htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 | 
					  htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 | 
				
			||||||
  htim8.Init.RepetitionCounter = 0;
 | 
					  htim8.Init.RepetitionCounter = 0;
 | 
				
			||||||
  htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 | 
					  htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 | 
				
			||||||
@ -268,10 +268,10 @@ void MX_TIM8_Init(void)
 | 
				
			|||||||
  {
 | 
					  {
 | 
				
			||||||
    Error_Handler();
 | 
					    Error_Handler();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
 | 
					  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE;
 | 
				
			||||||
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
 | 
					  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
 | 
				
			||||||
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
 | 
					  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
 | 
				
			||||||
  sConfigIC.ICFilter = 0;
 | 
					  sConfigIC.ICFilter = 15;
 | 
				
			||||||
  if (HAL_TIM_IC_ConfigChannel(&htim8, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
 | 
					  if (HAL_TIM_IC_ConfigChannel(&htim8, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Error_Handler();
 | 
					    Error_Handler();
 | 
				
			||||||
@ -364,6 +364,9 @@ void HAL_TIM_IC_MspInit(TIM_HandleTypeDef* tim_icHandle)
 | 
				
			|||||||
    GPIO_InitStruct.Alternate = GPIO_AF3_TIM8;
 | 
					    GPIO_InitStruct.Alternate = GPIO_AF3_TIM8;
 | 
				
			||||||
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 | 
					    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* TIM8 interrupt Init */
 | 
				
			||||||
 | 
					    HAL_NVIC_SetPriority(TIM8_CC_IRQn, 0, 0);
 | 
				
			||||||
 | 
					    HAL_NVIC_EnableIRQ(TIM8_CC_IRQn);
 | 
				
			||||||
  /* USER CODE BEGIN TIM8_MspInit 1 */
 | 
					  /* USER CODE BEGIN TIM8_MspInit 1 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* USER CODE END TIM8_MspInit 1 */
 | 
					  /* USER CODE END TIM8_MspInit 1 */
 | 
				
			||||||
@ -522,6 +525,8 @@ void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef* tim_icHandle)
 | 
				
			|||||||
    */
 | 
					    */
 | 
				
			||||||
    HAL_GPIO_DeInit(GPIOC, WS1_Pin|WS2_Pin);
 | 
					    HAL_GPIO_DeInit(GPIOC, WS1_Pin|WS2_Pin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* TIM8 interrupt Deinit */
 | 
				
			||||||
 | 
					    HAL_NVIC_DisableIRQ(TIM8_CC_IRQn);
 | 
				
			||||||
  /* USER CODE BEGIN TIM8_MspDeInit 1 */
 | 
					  /* USER CODE BEGIN TIM8_MspDeInit 1 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* USER CODE END TIM8_MspDeInit 1 */
 | 
					  /* USER CODE END TIM8_MspDeInit 1 */
 | 
				
			||||||
 | 
				
			|||||||
@ -276,6 +276,7 @@ NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
 | 
				
			|||||||
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
 | 
					NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
 | 
				
			||||||
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
 | 
					NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
 | 
				
			||||||
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
 | 
					NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
 | 
				
			||||||
 | 
					NVIC.TIM8_CC_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
 | 
				
			||||||
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
 | 
					NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
 | 
				
			||||||
PA0.GPIOParameters=GPIO_Label
 | 
					PA0.GPIOParameters=GPIO_Label
 | 
				
			||||||
PA0.GPIO_Label=A12
 | 
					PA0.GPIO_Label=A12
 | 
				
			||||||
@ -637,7 +638,13 @@ TIM6.Prescaler=4800-1
 | 
				
			|||||||
TIM6.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE
 | 
					TIM6.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE
 | 
				
			||||||
TIM8.Channel-Input_Capture1_from_TI1=TIM_CHANNEL_1
 | 
					TIM8.Channel-Input_Capture1_from_TI1=TIM_CHANNEL_1
 | 
				
			||||||
TIM8.Channel-Input_Capture2_from_TI2=TIM_CHANNEL_2
 | 
					TIM8.Channel-Input_Capture2_from_TI2=TIM_CHANNEL_2
 | 
				
			||||||
TIM8.IPParameters=Channel-Input_Capture2_from_TI2,Channel-Input_Capture1_from_TI1
 | 
					TIM8.ICFilter_CH1=15
 | 
				
			||||||
 | 
					TIM8.ICFilter_CH2=15
 | 
				
			||||||
 | 
					TIM8.ICPolarity_CH1=TIM_INPUTCHANNELPOLARITY_BOTHEDGE
 | 
				
			||||||
 | 
					TIM8.ICPolarity_CH2=TIM_INPUTCHANNELPOLARITY_BOTHEDGE
 | 
				
			||||||
 | 
					TIM8.IPParameters=Channel-Input_Capture2_from_TI2,Channel-Input_Capture1_from_TI1,Prescaler,Period,ICFilter_CH1,ICFilter_CH2,ICPolarity_CH1,ICPolarity_CH2
 | 
				
			||||||
 | 
					TIM8.Period=14999
 | 
				
			||||||
 | 
					TIM8.Prescaler=63
 | 
				
			||||||
VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg
 | 
					VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg
 | 
				
			||||||
VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP
 | 
					VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP
 | 
				
			||||||
VP_SYS_VS_Systick.Mode=SysTick
 | 
					VP_SYS_VS_Systick.Mode=SysTick
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user