📄 mac_mcu.c
字号:
* @return none
**************************************************************************************************
*/
void macMcuOverflowSetCompare(uint32 count)
{
halIntState_t s;
uint8 imBits;
MAC_ASSERT(!((count >> 16) & ~PEROF2_BITS)); /* illegal count value */
HAL_ENTER_CRITICAL_SECTION(s);
/* remember value of interrupt mask bits, allows OFCMPIM bit to be restored later */
imBits = T2PEROF2 & ~PEROF2_BITS;
/*
* Disable overflow compare interrupts. (It is OK to write zero to compare part of
* this register. Interrupts are disabled and the new value will be written and the
* interrupt flag cleared before interrupts are re-enabled.)
*/
T2PEROF2 = imBits & ~OFCMPIM;
T2PEROF2 = imBits & ~OFCMPIM; /* writing twice is chip bug workaround */
/* for efficiency, the 32-bit value is decoded using endian abstracted indexing */
T2PEROF0 = ((uint8 *)&count)[UINT32_NDX0];
T2PEROF1 = ((uint8 *)&count)[UINT32_NDX1];
/* see declaration of this shadow variable for more information */
shadowPerof2 = ((uint8 *)&count)[UINT32_NDX2];
/* write the compare value part of T2PEROF2 without re-enabling overflow compare interrupts */
T2PEROF2 = (imBits & ~OFCMPIM) | shadowPerof2;
T2PEROF2 = (imBits & ~OFCMPIM) | shadowPerof2; /* writing twice is chip bug workaround */
/*
* Now that new compare value is stored, clear the interrupt flag. This is important just
* in case a false match was generated as the multi-byte compare value was written.
*/
T2CNF = T2CNF_BASE_VALUE | (~OFCMPIF & T2CNF_IF_BITS);
/* re-enable overflow compare interrupts if they were previously enabled */
T2PEROF2 = imBits | shadowPerof2;
T2PEROF2 = imBits | shadowPerof2; /* writing twice is chip bug workaround */
HAL_EXIT_CRITICAL_SECTION(s);
}
/**************************************************************************************************
* @fn macMcuTimer2Isr
*
* @brief Interrupt service routine for timer2, the MAC timer.
*
* @param none
*
* @return none
**************************************************************************************************
*/
HAL_ISR_FUNCTION( macMcuTimer2Isr, T2_VECTOR )
{
uint8 t2perof2;
/* temporary variable used to suppress volatile access order warning */
t2perof2 = T2PEROF2;
/*------------------------------------------------------------------------------------------------
* Overflow compare interrupt - triggers when then overflow counter is
* equal to the overflow compare register.
*/
if ((T2CNF & OFCMPIF) & t2perof2)
{
/* call function for dealing with the timer compare interrupt */
macBackoffTimerCompareIsr();
/*
* NOTE : The interrupt flag for overflow compare is not cleared here. This is done
* in the code that sets a new overflow compare value.
*/
}
/*------------------------------------------------------------------------------------------------
* Overflow interrupt - triggers when the hardware timer rolls over.
*/
else if ((T2CNF & PERIF) & t2perof2)
{
/* call energy detect interrupt function, this interrupt not used for any other functionality */
mcuRecordMaxRssiIsr();
/* clear the interrupt flag by writing a zero to only that flag, write one to other flags */
T2CNF = T2CNF_BASE_VALUE | (~PERIF & T2CNF_IF_BITS);
}
}
/**************************************************************************************************
* @fn macMcuOrT2PEROF2
*
* @brief This function is used to OR the interrupt mask bits in register T2PERFOF2.
* Because of the hardware design a shadow register is required to preserve the
* other bits in this register. See the declaration of variable shadowPerof2 above
* for a full description.
*
* @param orValue - value to OR register with
*
* @return none
**************************************************************************************************
*/
void macMcuOrT2PEROF2(uint8 orValue)
{
halIntState_t s;
MAC_ASSERT(!(orValue & PEROF2_BITS)); /* only interrupt mask bits should be affected */
/*
* Perform OR operation only on interrupt mask bits. The shadow register preserves
* the value previously written to the other bits in the register.
*/
HAL_ENTER_CRITICAL_SECTION(s);
T2PEROF2 = ((T2PEROF2 & ~PEROF2_BITS) | orValue) | shadowPerof2;
T2PEROF2 = ((T2PEROF2 & ~PEROF2_BITS) | orValue) | shadowPerof2; /* writing twice is chip bug workaround */
HAL_EXIT_CRITICAL_SECTION(s);
}
/**************************************************************************************************
* @fn macMcuAndT2PEROF2
*
* @brief This function is used to AND the interrupt mask bits in register T2PERFOF2.
* Because of the hardware design a shadow register is required to preserve the
* other bits in this register. See the declaration of variable shadowPerof2 above
* for a full description.
*
* @param andValue - value to AND register with
*
* @return none
**************************************************************************************************
*/
void macMcuAndT2PEROF2(uint8 andValue)
{
halIntState_t s;
MAC_ASSERT((andValue & PEROF2_BITS) == PEROF2_BITS); /* only interrupt mask bits should be affected */
/*
* Perform AND operation only on interrupt mask bits. The shadow register preserves
* the value previously written to the other bits in the register.
*/
HAL_ENTER_CRITICAL_SECTION(s);
T2PEROF2 = ((T2PEROF2 & ~PEROF2_BITS) & andValue) | shadowPerof2;
T2PEROF2 = ((T2PEROF2 & ~PEROF2_BITS) & andValue) | shadowPerof2; /* writing twice is chip bug workaround */
HAL_EXIT_CRITICAL_SECTION(s);
}
/**************************************************************************************************
* @fn macMcuRfIsr
*
* @brief Interrupt service routine that handles all RF interrupts. There are a number
* of conditions "ganged" onto this one ISR so each condition must be tested for.
*
* @param none
*
* @return none
**************************************************************************************************
*/
HAL_ISR_FUNCTION( macMcuRfIsr, RF_VECTOR )
{
uint8 rfim;
rfim = RFIM;
if ((RFIF & IRQ_CSP_INT) & rfim)
{
/*
* Important! Because of how the CSP programs are written, CSP_INT interrupts should
* be processed before CSP_STOP interrupts. This becomes an issue when there are
* long critical sections.
*/
/* clear flag */
RFIF = ~IRQ_CSP_INT;
macCspTxIntIsr();
}
else if ((RFIF & IRQ_CSP_STOP) & rfim)
{
/* clear flag */
RFIF = ~IRQ_CSP_STOP;
macCspTxStopIsr();
}
else if ((RFIF & IRQ_TXDONE) & rfim)
{
/* disable interrupt - set up is for "one shot" operation */
HAL_DISABLE_INTERRUPTS();
RFIM &= ~IM_TXDONE;
HAL_ENABLE_INTERRUPTS();
//////////////////////////////////////////////////////////////////////////////////////////////
// REV_B_WORKAROUND : On Rev B parts the TXDONE signal does not fire for transmitted ACKs.
// As a workaround, the SFD signal is used instead (the TXDONE #defines used here have
// been redefined elsewhere to be SFD values). There is a problem with the SFD signal
// though... it fires at the *start* of an ACK. To get around this, the code pends until
// the TX_ACTIVE signal goes inactive. Ugly. Delete posthaste once Rev B is obsolete.
#ifndef _REMOVE_REV_B_WORKAROUNDS
while (RFSTATUS & TX_ACTIVE);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
macRxAckTxDoneCallback();
}
else if ((RFIF & IRQ_FIFOP) & rfim)
{
/* continue to execute interrupt handler as long as FIFOP is active */
do
{
macRxThresholdIsr();
RFIF = ~IRQ_FIFOP;
} while (RFSTATUS & FIFOP);
}
/////////////////////////////////////////////////////////////////////////////////////////
// REV_B_WORKAROUND : workaround for chip bug #297, replace with following code when fixed
/////////////////////////////////////////////////////////////////////////////////////////
#ifndef _REMOVE_REV_B_WORKAROUNDS
S1CON = 0x00;
HAL_DISABLE_INTERRUPTS();
rfim = RFIM;
if (RFIF & rfim)
{
S1CON = 0x03;
}
HAL_ENABLE_INTERRUPTS();
#else
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// keep this code, delete the rest
S1CON = 0x00;
RFIF = 0xFF;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#endif
/////////////////////////////////////////////////////////////////////////////////////////
}
/////////////////////////////////////////////////////////////////////////////////////////////
// REV_B_WORKAROUND : part of workaround for chip bug #297, delete it when possible
/////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _REMOVE_REV_B_WORKAROUNDS
/**************************************************************************************************
* @fn macMcuOrRFIM
*
* @brief Workaround code that should disappear when Rev B is obsolete.
*
* @param value - value to "or" into RFIM
*
* @return none
**************************************************************************************************
*/
void macMcuOrRFIM(uint8 value)
{
halIntState_t s;
HAL_ENTER_CRITICAL_SECTION(s);
S1CON = 0x00;
RFIM |= value;
{
uint8 rfim;
rfim = RFIM;
if (RFIF & rfim)
{
S1CON = 0x03;
}
}
HAL_EXIT_CRITICAL_SECTION(s);
}
/**************************************************************************************************
* @fn macMcuAndRFIM
*
* @brief Workaround code that should disappear when Rev B is obsolete.
*
* @param value - value to "and" into RFIM
*
* @return none
**************************************************************************************************
*/
void macMcuAndRFIM(uint8 value)
{
halIntState_t s;
HAL_ENTER_CRITICAL_SECTION(s);
S1CON = 0x00;
RFIM &= value;
{
uint8 rfim;
rfim = RFIM;
if (RFIF & rfim)
{
S1CON = 0x03;
}
}
HAL_EXIT_CRITICAL_SECTION(s);
}
/**************************************************************************************************
* @fn macMcuWriteRFIF
*
* @brief Workaround code that should disappear when Rev B is obsolete.
*
* @param value - value write to RFIF
*
* @return none
**************************************************************************************************
*/
void macMcuWriteRFIF(uint8 value)
{
halIntState_t s;
uint8 rfim;
HAL_ENTER_CRITICAL_SECTION(s);
RFIF = value;
S1CON = 0x00;
rfim = RFIM;
if (RFIF & rfim)
{
S1CON = 0x03;
}
HAL_EXIT_CRITICAL_SECTION(s);
}
#endif
/////////////////////////////////////////////////////////////////////////////////////////////
/**************************************************************************************************
* @fn macMcuRecordMaxRssiStart
*
* @brief Starts recording of the maximum received RSSI value.
*
* @param none
*
* @return none
**************************************************************************************************
*/
void macMcuRecordMaxRssiStart(void)
{
/* start maximum recorded value at the lowest possible value */
maxRssi = -128;
/* enable timer overflow interrupt */
macMcuOrT2PEROF2(PERIM);
}
/**************************************************************************************************
* @fn macMcuRecordMaxRssiStop
*
* @brief Stops recording of the maximum received RSSI. It returns the maximum value
* received since starting the recording.
*
* @param none
*
* @return maximum received RSSI value
**************************************************************************************************
*/
int8 macMcuRecordMaxRssiStop(void)
{
/* disable timer overflow interrupt */
macMcuAndT2PEROF2(~PERIM);
return(maxRssi);
}
/*=================================================================================================
* @fn macMcuRecordMaxRssiIsr
*
* @brief Interrupt service routine called during recording of max RSSI value.
*
* @param none
*
* @return none
*=================================================================================================
*/
static void mcuRecordMaxRssiIsr(void)
{
int8 rssi;
/* read latest RSSI value */
rssi = RSSIL;
/* if new RSSI value is greater than the maximum already received, it is the new maximum */
if (rssi > maxRssi)
{
maxRssi = rssi;
}
}
/**************************************************************************************************
* Compile Time Integrity Checks
**************************************************************************************************
*/
#if ((IRQ_SFD != IM_SFD) || (IRQ_FIFOP != IM_FIFOP) || (IRQ_TXDONE != IM_TXDONE))
#error "ERROR: Compile time error with RFIF vs RFIM register defines."
#endif
#if ((OFCMPIF != OFCMPIM) || (PERIF != PERIM) || (CMPIF != CMPIM))
#error "ERROR: Compile time error with T2CNF vs T2PEROF2 register defines."
#endif
/**************************************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -