- void * HALL_TIMx_CC_IRQHandler( void * pHandleVoid )
- {
- HALL_Handle_t * pHandle = ( HALL_Handle_t * ) pHandleVoid;
- TIM_TypeDef * TIMx = pHandle->TIMx;
- uint8_t bPrevHallState;
- uint32_t wCaptBuf;
- uint16_t hPrscBuf;
- uint16_t hHighSpeedCapture;
-
- if ( pHandle->SensorIsReliable )
- {
- /* A capture event generated this interrupt */
- bPrevHallState = pHandle->HallState;
-
- if ( pHandle->SensorPlacement == DEGREES_120 )
- {
- pHandle->HallState = LL_GPIO_IsInputPinSet( pHandle->H3Port, pHandle->H3Pin ) << 2
- | LL_GPIO_IsInputPinSet( pHandle->H2Port, pHandle->H2Pin ) << 1
- | LL_GPIO_IsInputPinSet( pHandle->H1Port, pHandle->H1Pin );
- }
- else
- {
- pHandle->HallState = ( LL_GPIO_IsInputPinSet( pHandle->H2Port, pHandle->H2Pin ) ^ 1 ) << 2
- | LL_GPIO_IsInputPinSet( pHandle->H3Port, pHandle->H3Pin ) << 1
- | LL_GPIO_IsInputPinSet( pHandle->H1Port, pHandle->H1Pin );
- }
-
- switch ( pHandle->HallState )
- {
- case STATE_5:
- if ( bPrevHallState == STATE_4 )
- {
- pHandle->Direction = POSITIVE;
- pHandle->MeasuredElAngle = pHandle->PhaseShift;
- }
- else if ( bPrevHallState == STATE_1 )
- {
- pHandle->Direction = NEGATIVE;
- pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift + S16_60_PHASE_SHIFT );
- }
- else
- {
- }
- break;
-
- case STATE_1:
- if ( bPrevHallState == STATE_5 )
- {
- pHandle->Direction = POSITIVE;
- pHandle->MeasuredElAngle = pHandle->PhaseShift + S16_60_PHASE_SHIFT;
- }
- else if ( bPrevHallState == STATE_3 )
- {
- pHandle->Direction = NEGATIVE;
- pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift + S16_120_PHASE_SHIFT );
- }
- else
- {
- }
- break;
-
- case STATE_3:
- if ( bPrevHallState == STATE_1 )
- {
- pHandle->Direction = POSITIVE;
- pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift + S16_120_PHASE_SHIFT );
- }
- else if ( bPrevHallState == STATE_2 )
- {
- pHandle->Direction = NEGATIVE;
- pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift + S16_120_PHASE_SHIFT +
- S16_60_PHASE_SHIFT );
- }
- else
- {
- }
-
- break;
-
- case STATE_2:
- if ( bPrevHallState == STATE_3 )
- {
- pHandle->Direction = POSITIVE;
- pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift + S16_120_PHASE_SHIFT
- + S16_60_PHASE_SHIFT );
- }
- else if ( bPrevHallState == STATE_6 )
- {
- pHandle->Direction = NEGATIVE;
- pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift - S16_120_PHASE_SHIFT );
- }
- else
- {
- }
- break;
-
- case STATE_6:
- if ( bPrevHallState == STATE_2 )
- {
- pHandle->Direction = POSITIVE;
- pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift - S16_120_PHASE_SHIFT );
- }
- else if ( bPrevHallState == STATE_4 )
- {
- pHandle->Direction = NEGATIVE;
- pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift - S16_60_PHASE_SHIFT );
- }
- else
- {
- }
- break;
-
- case STATE_4:
- if ( bPrevHallState == STATE_6 )
- {
- pHandle->Direction = POSITIVE;
- pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift - S16_60_PHASE_SHIFT );
- }
- else if ( bPrevHallState == STATE_5 )
- {
- pHandle->Direction = NEGATIVE;
- pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift );
- }
- else
- {
- }
- break;
-
- default:
- /* Bad hall sensor configutarion so update the speed reliability */
- //pHandle->SensorIsReliable = false;
-
- break;
- }
-
-
- #ifdef HALL_MTPA
- {
- pHandle->_Super.hElAngle = pHandle->MeasuredElAngle;
- }
- #endif
-
- /* Discard first capture */
- if ( pHandle->FirstCapt == 0u )
- {
- pHandle->FirstCapt++;
- LL_TIM_IC_GetCaptureCH1( TIMx );
- }
- else
- {
- /* used to validate the average speed measurement */
- if ( pHandle->BufferFilled < pHandle->SpeedBufferSize )
- {
- pHandle->BufferFilled++;
- }
-
- /* Store the latest speed acquisition */
- hHighSpeedCapture = LL_TIM_IC_GetCaptureCH1( TIMx );
- wCaptBuf = ( uint32_t )hHighSpeedCapture;
- hPrscBuf = LL_TIM_GetPrescaler ( TIMx );
-
- /* Add the numbers of overflow to the counter */
- wCaptBuf += ( uint32_t )pHandle->OVFCounter * 0x10000uL;
-
- if ( pHandle->OVFCounter != 0u )
- {
- /* Adjust the capture using prescaler */
- uint16_t hAux;
- hAux = hPrscBuf + 1u;
- wCaptBuf *= hAux;
-
- if ( pHandle->RatioInc )
- {
- pHandle->RatioInc = false; /* Previous capture caused overflow */
- /* Don't change prescaler (delay due to preload/update mechanism) */
- }
- else
- {
- if ( LL_TIM_GetPrescaler ( TIMx ) < pHandle->HALLMaxRatio ) /* Avoid OVF w/ very low freq */
- {
- LL_TIM_SetPrescaler ( TIMx, LL_TIM_GetPrescaler ( TIMx ) + 1 ); /* To avoid OVF during speed decrease */
- pHandle->RatioInc = true; /* new prsc value updated at next capture only */
- }
- }
- }
- else
- {
- /* If prsc preload reduced in last capture, store current register + 1 */
- if ( pHandle->RatioDec ) /* and don't decrease it again */
- {
- /* Adjust the capture using prescaler */
- uint16_t hAux;
- hAux = hPrscBuf + 2u;
- wCaptBuf *= hAux;
-
- pHandle->RatioDec = false;
- }
- else /* If prescaler was not modified on previous capture */
- {
- /* Adjust the capture using prescaler */
- uint16_t hAux = hPrscBuf + 1u;
- wCaptBuf *= hAux;
-
- if ( hHighSpeedCapture < LOW_RES_THRESHOLD ) /* If capture range correct */
- {
- if ( LL_TIM_GetPrescaler ( TIMx ) > 0u ) /* or prescaler cannot be further reduced */
- {
- LL_TIM_SetPrescaler ( TIMx, LL_TIM_GetPrescaler ( TIMx ) - 1 ); /* Increase accuracy by decreasing prsc */
- /* Avoid decrementing again in next capt.(register preload delay) */
- pHandle->RatioDec = true;
- }
- }
- }
- }
-
- #if 0
- /* Store into the buffer */
- /* Null Speed is detected, erase the buffer */
- if ( wCaptBuf > pHandle->MaxPeriod )
- {
- uint8_t bIndex;
- for ( bIndex = 0u; bIndex < pHandle->SpeedBufferSize; bIndex++ )
- {
- pHandle->SensorSpeed[bIndex] = 0;
- }
- pHandle->BufferFilled = 0 ;
- pHandle->SpeedFIFOSetIdx = 1;
- pHandle->SpeedFIFOGetIdx = 0;
- /* Indicate new speed acquisitions */
- pHandle->NewSpeedAcquisition = 1;
- pHandle->ElSpeedSum = 0;
- }
- /* Filtering to fast speed... could be a glitch ? */
- /* the HALL_MAX_PSEUDO_SPEED is temporary in the buffer, and never included in average computation*/
- else
- #endif
- if ( wCaptBuf < pHandle->MinPeriod )
- {
- pHandle->CurrentSpeed = HALL_MAX_PSEUDO_SPEED;
- pHandle->NewSpeedAcquisition = 0;
- }
- else
- {
- pHandle->ElSpeedSum -= pHandle->SensorSpeed[pHandle->SpeedFIFOIdx]; /* value we gonna removed from the accumulator */
- if ( wCaptBuf >= pHandle->MaxPeriod )
- {
- pHandle->SensorSpeed[pHandle->SpeedFIFOIdx] = 0;
- }
- else
- {
- pHandle->SensorSpeed[pHandle->SpeedFIFOIdx] = ( int16_t ) ( pHandle->PseudoFreqConv / wCaptBuf );
- pHandle->SensorSpeed[pHandle->SpeedFIFOIdx] *= pHandle->Direction;
- pHandle->ElSpeedSum += pHandle->SensorSpeed[pHandle->SpeedFIFOIdx];
- }
- /* Update pointers to speed buffer */
- pHandle->CurrentSpeed = pHandle->SensorSpeed[pHandle->SpeedFIFOIdx];
- pHandle->SpeedFIFOIdx++;
- if ( pHandle->SpeedFIFOIdx == pHandle->SpeedBufferSize )
- {
- pHandle->SpeedFIFOIdx = 0u;
- }
- /* Indicate new speed acquisitions */
- pHandle->NewSpeedAcquisition = 1;
- }
- /* Reset the number of overflow occurred */
- pHandle->OVFCounter = 0u;
- }
- }
- return MC_NULL;
- }
|