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 FDCAN1_IT1_IRQHandler(void);
 | 
			
		||||
void FDCAN2_IT1_IRQHandler(void);
 | 
			
		||||
void TIM8_CC_IRQHandler(void);
 | 
			
		||||
/* USER CODE BEGIN 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};
 | 
			
		||||
 | 
			
		||||
static uint8_t  pwm_ch_active[8];
 | 
			
		||||
 | 
			
		||||
static uint16_t wss_flanks[2];
 | 
			
		||||
/* USER CODE END PV */
 | 
			
		||||
 | 
			
		||||
/* Private function prototypes -----------------------------------------------*/
 | 
			
		||||
@ -164,6 +166,10 @@ int main(void)
 | 
			
		||||
  // Init all channels as stopped
 | 
			
		||||
  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 */
 | 
			
		||||
 | 
			
		||||
  /* Infinite loop */
 | 
			
		||||
@ -207,7 +213,8 @@ int main(void)
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case FIN:
 | 
			
		||||
              /* NYI */
 | 
			
		||||
              value = wss_flanks[signal->channel];
 | 
			
		||||
              wss_flanks[signal->channel] = 0;
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            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) {
 | 
			
		||||
  (&(Instance->CCR1))[ch] = dc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -59,6 +59,7 @@ extern DMA_HandleTypeDef hdma_adc1;
 | 
			
		||||
extern ADC_HandleTypeDef hadc1;
 | 
			
		||||
extern FDCAN_HandleTypeDef hfdcan1;
 | 
			
		||||
extern FDCAN_HandleTypeDef hfdcan2;
 | 
			
		||||
extern TIM_HandleTypeDef htim8;
 | 
			
		||||
/* USER CODE BEGIN EV */
 | 
			
		||||
 | 
			
		||||
/* USER CODE END EV */
 | 
			
		||||
@ -285,6 +286,20 @@ void FDCAN2_IT1_IRQHandler(void)
 | 
			
		||||
  /* 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 END 1 */
 | 
			
		||||
 | 
			
		||||
@ -251,9 +251,9 @@ void MX_TIM8_Init(void)
 | 
			
		||||
 | 
			
		||||
  /* USER CODE END TIM8_Init 1 */
 | 
			
		||||
  htim8.Instance = TIM8;
 | 
			
		||||
  htim8.Init.Prescaler = 0;
 | 
			
		||||
  htim8.Init.Prescaler = 63;
 | 
			
		||||
  htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
 | 
			
		||||
  htim8.Init.Period = 65535;
 | 
			
		||||
  htim8.Init.Period = 14999;
 | 
			
		||||
  htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 | 
			
		||||
  htim8.Init.RepetitionCounter = 0;
 | 
			
		||||
  htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 | 
			
		||||
@ -268,10 +268,10 @@ void MX_TIM8_Init(void)
 | 
			
		||||
  {
 | 
			
		||||
    Error_Handler();
 | 
			
		||||
  }
 | 
			
		||||
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
 | 
			
		||||
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE;
 | 
			
		||||
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
 | 
			
		||||
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
 | 
			
		||||
  sConfigIC.ICFilter = 0;
 | 
			
		||||
  sConfigIC.ICFilter = 15;
 | 
			
		||||
  if (HAL_TIM_IC_ConfigChannel(&htim8, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    Error_Handler();
 | 
			
		||||
@ -364,6 +364,9 @@ void HAL_TIM_IC_MspInit(TIM_HandleTypeDef* tim_icHandle)
 | 
			
		||||
    GPIO_InitStruct.Alternate = GPIO_AF3_TIM8;
 | 
			
		||||
    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 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);
 | 
			
		||||
 | 
			
		||||
    /* TIM8 interrupt Deinit */
 | 
			
		||||
    HAL_NVIC_DisableIRQ(TIM8_CC_IRQn);
 | 
			
		||||
  /* USER CODE BEGIN TIM8_MspDeInit 1 */
 | 
			
		||||
 | 
			
		||||
  /* USER CODE END TIM8_MspDeInit 1 */
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user