📄 phy_hw_setup.c
字号:
// MSB = CCA Energy detect threshold: abs(power in dBm)*2, 0x96=-75dBm
// LSB = Power compensation Offset added to RSSI. Typically 0x74 FFJ/JK 13/01/04 (Abel 013)
ABEL_WRITE(ABEL_reg4, NV_RAM_ptr->Abel_HF_Calibration);
// Now set up various register from the tables (see tables above)
for (idx = 0; idx < sizeof(setupAddrTable)/sizeof(setupAddrTable[0]); idx++) {
addr = setupAddrTable[idx]; // It saves a few code bytes to use a stack variable
ABEL_WRITE(addr, setupValueTable[idx]);
}
ABEL_READ(ABEL_STATUS_REG, retReg); // Clear interrupts by reading interrupt status
ABEL_WRITE(ABEL_TMR2_HI_REG, 0x0000); // Enable TMR2 interrupts
IRQSC = 0x17; // Enable external interrupt from Abel, low level and edge-triggered
}
/*************************************************************************************
* Used by JT to make PHY speed test (Header calculation) *
*************************************************************************************/
#if gAspPowerSaveCapability_d
void WakeUpIsr(void)
{
// Dont do anything if we are already awake (ATTN IRQ will always cause
// this ISR to be called even though the ABEL is out of pover save mode).
if(gSeqPowerSaveMode != 0) {
uint16_t ctrl2val, maskval;
SeqGenerateWakeInd();
gSeqPowerSaveMode = 0; // Set to gSeqPowerModeAwake_c;
// Disable ATTN Irq when not in low power mode
ABEL_READ_INT(ABEL_MASK_REG, maskval);
maskval=maskval & (~cATTN_MASK);
ABEL_WRITE_INT(ABEL_MASK_REG, maskval);
ctrl2val=0x7c00 | cABEL2SPI_MASK | cUSE_STRM_MODE;
#ifdef USE_INTERRUPT_TXEOF
ctrl2val = ctrl2val | (uint16_t) cTX_DONE_MASK;
#endif
#ifdef USE_INTERRUPT_RXEOF
ctrl2val = ctrl2val | (uint16_t) cRX_DONE_MASK;
#endif
ABEL_WRITE(ABEL_CONTROL2_REG, ctrl2val);
// Don't attempt to setup clock if clko is already running..
// Attempting to do so will cause an undeterministic wakeup time!!
if (gSeqClkoState == 0) // Check if equal to gSeqClkoStateDisabled_c
{
gSeqClkoState = 1; // Set to gSeqClkoStateEnabled_c (clko running)
// Setup clock again
#if defined BOOTLOADER_ENABLED && !defined FOR_BOOTLOADER_ONLY
// Call version in bootloader
FL_ICG_Setup();
#else
ICG_Setup(); // Reuse code in function to reduce code size
#endif defined BOOTLOADER_ENABLED && !defined FOR_BOOTLOADER_ONLY
} // if - clko restore..
} // if - power save mode..
}
#endif // gAspPowerSaveCapability_d
/*************************************************************************************
* Must signal to gIsrAsyncTailFunction/Header calculation, that the calculation must *
* stop now, or receiver to be restarted. *
*************************************************************************************/
void LO_LOCK_IRQ(void)
{
// Handle Lo1 unlock
// If current action is Rx (typical), merely restart Rx, ensuring that TO did not just occur.
// If current action is Tx, act as if everything went ok here by calling fast action TxEof code.
// If either Ed of Cca should get Lo1 unlock, fast action is already set up for Eof
// and will have been called on irq H-L, so ignore here!
if (mPhyTxRxState==cBusy_Rx) RestartRxOrTimeout();
if (mPhyTxRxState==cBusy_Tx) {
ABEL_READ_INT(ABEL_CURR_TIME_LSB_REG, gRxTimeStamp);
gRxTimeStamp = gRxTimeStamp - aAckSize_s;
DoFastTxEof();
}
}
/*************************************************************************************
* This is where everything happens... Abel driver runs through here *
*************************************************************************************/
__interrupt void AbelInterrupt(void)
{
uint16_t retReg;
uint8_t *pTmp;
register uint8_t tmpStatus;
#ifdef TIME_INTERRUPT
uint8_t tmpRunning;
tmpRunning = CHECK_ABEL_ISR_RUNNING_1;
ABEL_ISR_RUNNING_1;
#endif
ISR_DISABLED_0;
if (gIsrSuperFastAction){
gIsrSuperFastAction();
gIsrSuperFastAction=NULL;
mpfPendingSetup = NULL;
}
tmpStatus = IRQSC;
tmpStatus |= 0x04; // IACK, MUST be done before RxStreaming...
tmpStatus &= ~0x02; // 0x02 = DISABLE ABEL ISR
IRQSC = tmpStatus;
SETTIMINGPIN_0
gIsrEntryCounter++;
gIsrMask = 0xFFFF;
ENABLE_ALL_INTERRUPTS; // Interrupts are always enabled in this system. Disable ABEL only when needed
(gIsrFastAction)();
if(IRQSC & 0x08) //IRQF test
{
IRQSC |= 0x04; //IACK, Could be initiated by new/next edge.
ABEL_READ_INT(ABEL_reg24, retReg);
// If interrupt other than streaming Rx occured kill filter.
retReg = retReg & gIsrMask;
if (retReg & 0xFF00)
{
gStopAsyncRx = TRUE;
if (retReg & cLO_LOCK_IRQ){ LO_LOCK_IRQ(); {if (retReg & cTMR4_IRQ) RxTimeout();} goto IsrExit;}
#ifdef USE_INTERRUPT_RXEOF
if (retReg & cRX_DONE){ PhyPlmeSyncLossIndication(); goto IsrExit;}
#else
if (retReg & cRX_DONE) DummyISR();
#endif
#ifdef USE_INTERRUPT_TXEOF
if (retReg & cTX_DONE){ DoFastTxEof(); goto IsrExit;} ///*PhyPlmeSyncLossIndication();*/} //HACK for Timeout in TxAck
#else
if (retReg & cTX_DONE) DummyISR();
#endif
if (retReg & cTMR1_IRQ) pTimer1Isr();
#if gAspPowerSaveCapability_d
if (retReg & cResetATTN_IRQ) WakeUpIsr();
if (retReg & cDOZE_IRQ) WakeUpIsr();
#endif // gAspPowerSaveCapability_d
if (retReg & (cSTRM_DATA_ERR | cHG_IRQ)) {
gStopAsyncRx = FALSE;
DummyISR();
}
}
if (retReg & (0x00FC & ~cRX_RCVD_IRQ)) //@RNI: ignore cRX_RCVD_IRQ
{
gStopAsyncRx = TRUE;
if (retReg & cCCA_IRQ) DummyISR(); // Ignore CCA irq here. Fast action catches it. (Otherwise ignore the failure)
if (retReg & cTMR2_IRQ) gpTimer2Isr();
if (retReg & cTMR4_IRQ){ RxTimeout(); goto IsrExit;}
if (retReg & cTMR3_IRQ) DummyISR();
//if (retReg & cRX_RCVD_IRQ) StreamingRxError++;
if (retReg & cTX_SENT_IRQ) StreamingTxError++;
}
}
gIsrAsyncTailFunction();
IsrExit:
// Assume that interrupts are DISABLED at this point!
pTmp = &gIsrEntryCounter;
if (!(--*pTmp)){
if (gSeqInErrorState){
SeqIsrCompletedInErrorState();
}
}
DISABLE_ALL_INTERRUPTS;
ENABLE_ABEL_INTERRUPTS_FAST;
CLRTIMINGPIN_0
#ifdef TIME_INTERRUPT
if (tmpRunning == 0) ABEL_ISR_DONE_1; // Ensure measuring entire time of nested interrupts!
#endif
ISR_ENABLED_0;
}
/************************************************************************************
*************************************************************************************
* Public function(s)
*************************************************************************************
************************************************************************************/
/*******************************************************************
* Setup everything *
*******************************************************************/
void PHY_HW_Setup(void)
{
InitPHYIO();
InitAbelSPI();
HWResetAbel();
}
/*******************************************************************************
* Pulse ATTN pin of the ABEL radio in order to bring it out of power save mode *
*******************************************************************************/
void AbelWakeUp(void)
{
#if defined(AttEnable) && defined(AttDisable)
uint8_t i=10; // ~10us ATTN pulse @ 62.5KHz
AttEnable;
while(i) { i--; }
AttDisable;
// Wait for ICG to lock onto operational clock frequency.
if(((ICGS1 & ICG_FLL_LOCKED) != ICG_FLL_LOCKED)) {
while((ICGS1 & ICG_FLL_LOCKED) != ICG_FLL_LOCKED) {}
}
#endif
}
// **************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -