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;
}
|