//------------------------------------------------------------------------------------------------ // Function Name // timerIntT0_ISR() // // Return Value : None // Parameters : None // // This is the Interrupt Service Routing for the T0 timer. The T0 timer is used for all MAC // time outs and MAC timing events. The T0 time base uses SYSCLK/4 for all supported SYSCLK // frequencies. The time outs are calculated using macros or calculated by the initialization // or register write API functions. Since some time outs require long periods a 24-bit timer // has been implemented using a global variable for the most significant byte. If the MSB of the // timer (EZMacProTimerMSB) is non-zero, it will be decrement and the ISR will be called again // when the timer overflows. // // This function disables the timer interrupts before executing the state machines. If a // timeout event is to initiate another timeout event, the timerIntTimeout() function should // be used. // // The Basic States (Wake-up, Receive, and Transmit) are implemented using if..else if bit // tests for the corresponding bit in the master control register. The detailed TX and RX // state machines are implemented in separate functions. // // Conditional compile time switches remove the TX or RX state machines for the RX only and // and TX only builds. // // The timer interrupt should not call functions from other modules. This would create cause // a multiple call to segment warning and result in poor RAM usage. // //----------------------------------------------------------------------------------------------- INTERRUPT(timerIntT3_ISR, INTERRUPT_TIMER3) { U8 state; if (EZMacProTimerMSB == 0) { DISABLE_MAC_TIMER_INTERRUPT(); STOP_MAC_TIMER(); CLEAR_MAC_TIMER_INTERRUPT(); state = EZMacProReg.name.MSR & 0x0F; if (EZMacProReg.name.MSR == EZMAC_PRO_WAKE_UP) {//if the MAC is in Wake up state call the WakeUp function timerIntWakeUp(); } #ifndef RECEIVER_ONLY_OPERATION else if ((EZMacProReg.name.MSR & TX_STATE_BIT) == TX_STATE_BIT) {//if the MAC is in transmit state then call the transmit state machine timerIntTX_StateMachine(state); } #endif #ifndef TRANSMITTER_ONLY_OPERATION else if ((EZMacProReg.name.MSR & RX_STATE_BIT) == RX_STATE_BIT) {//if the MAC is in receive state then call the receiver timerIntRX_StateMachine(state); } #endif else { } } else { CLEAR_MAC_TIMER_INTERRUPT(); EZMacProTimerMSB--; } }
/* * 该函数用于设置16-bit定时器 * * time[15, 0] -- 定时器溢出时间 * time[31, 16] -- 定时器溢出次数 * timeout_cnt -- 用来记录定时器溢出次数的变量, 在ISR中使用 * */ void set_timeout_and_start_timer(U32 longTime) { UU32 time; U16 timeout; DISABLE_MAC_TIMER_INTERRUPT(); // Disable Timer interrupt STOP_MAC_TIMER(); // Stop Timer if (0 != is_mac_timer_inuse) { /* 用于检测定时器使用的冲突, 如果有冲突说明状态控制有异常, 暂时不做处理 */ } is_mac_timer_inuse = 1; time.U32 = longTime; if (longTime > 65535) { EZMacProTimerMSB = time.U16[MSB]; timeout = 65535; } else { EZMacProTimerMSB = 0; timeout = time.U16[LSB]; } EZMacProTimerLSB = time.U16[LSB]; #if C51_SYNTAX_ time.U16[LSB] = -time.U16[LSB]; TIMER_LOW_BYTE = time.U8[b0]; // write LSB first TIMER_HIGH_BYTE = time.U8[b1]; // write MSB last #else init_si4432_mac_timer(timeout); #endif CLEAR_MAC_TIMER_INTERRUPT(); // Clear Timer interrupt START_MAC_TIMER(); // Start Timer return; }
void timerIntRX_StateMachine (U8 state) { U8 temp8; #ifdef PACKET_FORWARDING_SUPPORTED U32 timeout; #endif//PACKET_FORWARDING_SUPPORTED switch (state) { #ifdef FOUR_CHANNEL_IS_USED case RX_STATE_FREQUENCY_SEARCH: // jump to the next channel if search mechanism is enabled if((EZMacProReg.name.RCR & 0x04) == 0x04) { timerIntNextRX_Channel(); } // start timer with channel search timeout timerIntTimeout(TimeoutChannelSearch); ENABLE_MAC_TIMER_INTERRUPT(); break; #endif //FOUR_CHANNEL_IS_USED #ifdef MORE_CHANNEL_IS_USED case RX_STATE_FREQUENCY_SEARCH: //check the channel number if (SelectedChannel < (maxChannelNumber - 1)) { //jump to the next channel SelectedChannel++; //switch off the receiver timerIntSetFunction1(SI4432_XTON); timerIntSpiWriteReg (SI4432_FREQUENCY_HOPPING_CHANNEL_SELECT,EZMacProReg.array[FR0+SelectedChannel]); //switch on the receiver timerIntSetFunction1(SI4432_XTON|SI4432_RXON); // start timer with channel search timeout timerIntTimeout(TimeoutChannelSearch); ENABLE_MAC_TIMER_INTERRUPT(); } else { //jump to the first channel SelectedChannel = 0; //switch off the receiver timerIntSetFunction1(SI4432_XTON); timerIntSpiWriteReg (SI4432_FREQUENCY_HOPPING_CHANNEL_SELECT,EZMacProReg.array[FR0+SelectedChannel]); //switch on the receiver timerIntSetFunction1(SI4432_XTON|SI4432_RXON); // start timer with channel search timeout timerIntTimeout(TimeoutChannelSearch); ENABLE_MAC_TIMER_INTERRUPT(); } break; #endif//MORE_CHANNEL_IS_USED case RX_STATE_WAIT_FOR_PACKET: //set the dinamic plength if it is needed otherwise set the fix length if ((EZMacProReg.name.MCR & 0x04) == 0x04) { temp8 = timerIntSpiReadReg(SI4432_HEADER_CONTROL_2); temp8 &= ~0x08; timerIntSpiWriteReg(SI4432_HEADER_CONTROL_2, temp8); } else { timerIntSpiWriteReg(SI4432_TRANSMIT_PACKET_LENGTH, EZMacProReg.name.PLEN); } #ifdef MORE_CHANNEL_IS_USED case RX_STATE_WAIT_FOR_PREAMBLE: #endif//MORE_CHANNEL_IS_USED case RX_STATE_WAIT_FOR_SYNC: // RX error - HW error or bad timeout calculation //switch off the receiver timerIntSetFunction1(SI4432_XTON); // clear interrupt enable 1 timerIntSpiWriteReg(SI4432_INTERRUPT_ENABLE_1, 0x00); #ifdef FOUR_CHANNEL_IS_USED //Enable the Preamble valid interrupt timerIntSetEnable2(SI4432_ENPREAVAL); // jump to the next channel if search mechanism is enabled if((EZMacProReg.name.RCR & 0x04) == 0x04) { timerIntNextRX_Channel(); } // start timer with channel search timeout timerIntTimeout(TimeoutChannelSearch); ENABLE_MAC_TIMER_INTERRUPT(); #endif//FOUR_CHANNEL_IS_USED #ifdef MORE_CHANNEL_IS_USED //enable the preamble valid interrupt timerIntSetEnable2(SI4432_ENPREAVAL); //determine the next channel number if (SelectedChannel < (maxChannelNumber - 1)) { SelectedChannel++; } else { SelectedChannel = 0; } //jump to the next channel timerIntSpiWriteReg (SI4432_FREQUENCY_HOPPING_CHANNEL_SELECT,EZMacProReg.array[FR0+SelectedChannel]); // start timer with channel search timeout timerIntTimeout(TimeoutChannelSearch); ENABLE_MAC_TIMER_INTERRUPT(); #endif//MORE_CHANNEL_IS_USED //enable the receiver timerIntSetFunction1(SI4432_RXON|SI4432_XTON); //go to the next channel EZMacProReg.name.MSR = RX_STATE_BIT | RX_STATE_FREQUENCY_SEARCH; break; #ifdef EXTENDED_PACKET_FORMAT #ifndef RECEIVER_ONLY_OPERATION case RX_STATE_WAIT_FOR_SEND_ACK: // SW error #ifdef ANTENNA_DIVERSITY_ENABLED #ifndef B1_ONLY //if revision V2 or A0 chip is used if ((EZMacProReg.name.DTR == 0x00) || (EZMacProReg.name.DTR == 0x01)) { //switch ON the internal algorithm temp8 = timerIntSpiReadReg(SI4432_OPERATING_AND_FUNCTION_CONTROL_2); timerIntSpiWriteReg (SI4432_OPERATING_AND_FUNCTION_CONTROL_2, temp8 | 0x80); //the gpios control the rf chip automatically timerIntSpiWriteReg(SI4432_GPIO1_CONFIGURATION, 0x17); timerIntSpiWriteReg(SI4432_GPIO2_CONFIGURATION, 0x18); } #endif//B1_ONLY #endif//ANTENNA_DIVERSITY_ENABLED #ifndef PACKET_FORWARDING_SUPPORTED //set back the preamble length #ifdef FOUR_CHANNEL_IS_USED timerIntSpiWriteReg(SI4432_PREAMBLE_LENGTH, PreamRegValue); #endif//FOUR_CHANNEL_IS_USED #ifdef MORE_CHANNEL_IS_USED temp8 = timerIntSpiReadReg(SI4432_HEADER_CONTROL_2); timerIntSpiWriteReg(SI4432_HEADER_CONTROL_2, (temp8 | 0x01)); timerIntSpiWriteReg(SI4432_PREAMBLE_LENGTH, PreamRegValue); #endif//MORE_CHANNEL_IS_USED #endif//PACKET_FORWARDING_SUPPORTED //go to the RX ERROR STATE EZMacProReg.name.MSR = (RX_STATE_BIT | RX_ERROR_STATE); //Call the Error state entered callback. EZMacPRO_StateErrorEntered(); break; #endif//RECEIVER_ONLY_OPERATION #endif//EXTENDED_PACKET_FORMAT #ifdef PACKET_FORWARDING_SUPPORTED #ifdef TRANSCEIVER_OPERATION case RX_STATE_FORWARDING_LBT_START_LISTEN: if(BusyLBT == 0) {//the channel was free during the first 0.5ms ChannelOccupiedInStartPeriod = 0; // start timer with fix 4.5ms timeout timerIntTimeout(LBT_FIXED_TIME_4500US); //go to the next state EZMacProReg.name.MSR = RX_STATE_BIT | RX_STATE_FORWARDING_LBT_LISTEN; // disable the receiver timerIntSetFunction1(SI4432_XTON); // enable the receiver again timerIntSetFunction1( SI4432_RXON|SI4432_XTON); ENABLE_MAC_TIMER_INTERRUPT(); } else {//the channnel was busy during the first 0.5ms BusyLBT = 0; ChannelOccupiedInStartPeriod = 1; ChannelOccupiedCounter = 0; // start timer with fix 1ms timeout timerIntTimeout(LBT_FIXED_TIME_1000US); // go to the next state EZMacProReg.name.MSR = RX_STATE_BIT | RX_STATE_FORWARDING_LBT_LISTEN; // disable the receiver timerIntSetFunction1(SI4432_XTON); // enable the receiver again timerIntSetFunction1( SI4432_RXON|SI4432_XTON); ENABLE_MAC_TIMER_INTERRUPT(); } break; case RX_STATE_FORWARDING_LBT_LISTEN: if (ChannelOccupiedInStartPeriod == 0) {//the channel was free during the 0.5ms start period if(BusyLBT == 0) {// LBT passed, channel should be clear in the fix 4.5ms period //disable the receiver timerIntSetFunction1(SI4432_XTON); // clear enable 2 interrupt timerIntSetEnable2(0x00); // enable ENPKSENT bit timerIntSpiWriteReg(SI4432_INTERRUPT_ENABLE_1, SI4432_ENPKSENT); // enable TX timerIntSetFunction1( SI4432_TXON|SI4432_XTON); // start timer with packet transmit timeout timerIntTimeout(TimeoutTX_Packet); //go to the next state EZMacProReg.name.MSR = RX_STATE_BIT | RX_STATE_FORWARDING_WAIT_FOR_TX; ENABLE_MAC_TIMER_INTERRUPT(); } else {//the channel was busy during the 4.5ms BusyLBT = 0; // multiple by fixed plus random number timeout = LBT_FIXED_TIME_5000US + TimeoutLBTI * (U32)(timerIntRandom()); // start timer with timeout timerIntTimeout(timeout); //got to the next state EZMacProReg.name.MSR = RX_STATE_BIT | RX_STATE_FORWARDING_LBT_RANDOM_LISTEN; // disable the receiver timerIntSetFunction1(SI4432_XTON); // enable the receiver again timerIntSetFunction1( SI4432_RXON|SI4432_XTON); ENABLE_MAC_TIMER_INTERRUPT(); } } else {//the channel was busy during the 0.5ms start period if(BusyLBT == 0) {// LBT passed, channel should be clear in the fix 1ms period // multiple by fixed plus random number timeout = LBT_FIXED_TIME_5000US + TimeoutLBTI * (U32)(timerIntRandom()); // start timer with timeout timerIntTimeout(timeout); //go to the next state EZMacProReg.name.MSR = RX_STATE_BIT | RX_STATE_FORWARDING_LBT_RANDOM_LISTEN; ENABLE_MAC_TIMER_INTERRUPT(); } else {//the channel was busy in the fix 1ms period if (ChannelOccupiedCounter < 9) { BusyLBT = 0; ChannelOccupiedCounter++; // start timer with fix 1ms timeout timerIntTimeout(LBT_FIXED_TIME_1000US); //go to the next state EZMacProReg.name.MSR = RX_STATE_BIT | RX_STATE_FORWARDING_LBT_LISTEN; // disable the receiver timerIntSetFunction1(SI4432_XTON); // enable the receiver again timerIntSetFunction1( SI4432_RXON|SI4432_XTON); ENABLE_MAC_TIMER_INTERRUPT(); } else {//the channel was busy during the 10*1ms BusyLBT = 0; EZMacProLBT_Retrys++; if(EZMacProLBT_Retrys < MAX_LBT_RETRIES) {//the channel was busy and the retries didn't reach the maximum value // disable the reciever timerIntSetFunction1(SI4432_XTON); // start timer with fix ETSI timeout timerIntTimeout(TIMEOUT_LBTI_ETSI); //go to the next state EZMacProReg.name.MSR = RX_STATE_BIT | RX_STATE_FORWARDING_LBT_START_LISTEN; ENABLE_MAC_TIMER_INTERRUPT(); // enable the receiver again timerIntSetFunction1( SI4432_RXON|SI4432_XTON); } else {//the channel was busy and the retries reach the maximum value //disable the receiver timerIntSetFunction1(SI4432_XTON); //go to the next state EZMacProReg.name.MSR = RX_STATE_BIT | RX_ERROR_FORWARDING_WAIT_FOR_TX; #ifdef FOUR_CHANNEL_IS_USED //increment error counter timerIntIncrementError(EZMAC_PRO_ERROR_CHANNEL_BUSY); #endif//FOUR_CHANNEL_IS_USED //call the LBT error callback function EZMacPRO_LBTTimeout(); } } } } break; case RX_STATE_FORWARDING_LBT_RANDOM_LISTEN: if(BusyLBT == 0) {// the channel was free during the 5ms + random period //disable the receiver timerIntSetFunction1(SI4432_XTON); // clear enable 2 interrupt timerIntSetEnable2(0x00); // enable ENPKSENT bit timerIntSpiWriteReg(SI4432_INTERRUPT_ENABLE_1, SI4432_ENPKSENT); // enable TX timerIntSetFunction1( SI4432_TXON|SI4432_XTON); // start timer with fix transmit packet timeout timerIntTimeout(TimeoutTX_Packet); //go to the next state EZMacProReg.name.MSR = RX_STATE_BIT | RX_STATE_FORWARDING_WAIT_FOR_TX; ENABLE_MAC_TIMER_INTERRUPT(); } else {//the channel was busy during the 5ms + random period BusyLBT = 0; EZMacProLBT_Retrys++; if(EZMacProLBT_Retrys < MAX_LBT_RETRIES) {//the channel was busy and the retries didn't reach the maximum value // disable the reciever timerIntSetFunction1(SI4432_XTON); // start timer with fix ETSI timeout timerIntTimeout(TIMEOUT_LBTI_ETSI); // go to the next state EZMacProReg.name.MSR = RX_STATE_BIT | RX_STATE_FORWARDING_LBT_START_LISTEN; ENABLE_MAC_TIMER_INTERRUPT(); // enable the receiver again timerIntSetFunction1( SI4432_RXON|SI4432_XTON); } else {//the channel was busy and the retries reach the maximum value //disable the receiver timerIntSetFunction1(SI4432_XTON); //go to the next state EZMacProReg.name.MSR = RX_STATE_BIT | RX_ERROR_FORWARDING_WAIT_FOR_TX; #ifdef FOUR_CHANNEL_IS_USED //increment the error counter timerIntIncrementError(EZMAC_PRO_ERROR_CHANNEL_BUSY); #endif//FOUR_CHANNEL_IS_USED //cll the LBT error callback function EZMacPRO_LBTTimeout(); } } break; #endif // TRANSCEIVER_OPERATION case RX_STATE_FORWARDING_WAIT_FOR_TX: // TX timeout - HW error or bad timeout calculation //if there is a TX error then switch back the internal antenna diversity algorthm #ifdef ANTENNA_DIVERSITY_ENABLED #ifndef B1_ONLY //if revision V2 or A0 chip is used if ((EZMacProReg.name.DTR == 0x00) || (EZMacProReg.name.DTR == 0x01)) { //switch ON the internal algorithm temp8 = timerIntSpiReadReg(SI4432_OPERATING_AND_FUNCTION_CONTROL_2); timerIntSpiWriteReg (SI4432_OPERATING_AND_FUNCTION_CONTROL_2, temp8 | 0x80); //the gpios control the rf chip automatically timerIntSpiWriteReg(SI4432_GPIO1_CONFIGURATION, 0x17); timerIntSpiWriteReg(SI4432_GPIO2_CONFIGURATION, 0x18); } #endif//B1_ONLY #endif//ANTENNA_DIVERSITY_ENABLED EZMacProReg.name.MSR = RX_STATE_BIT | RX_ERROR_STATE; //Call the Error state entered callback. EZMacPRO_StateErrorEntered(); break; #endif // PACKET_FORWARDING_SUPPORTED case RX_ERROR_STATE: DISABLE_MAC_INTERRUPTS(); // clear EX0 & ET0 // disable all Si443x interrupt sources timerIntSpiWriteReg(SI4432_INTERRUPT_ENABLE_1, 0x00); timerIntSetEnable2(0x00); // clear interrupts timerIntSpiReadReg(SI4432_INTERRUPT_STATUS_1); timerIntSpiReadReg(SI4432_INTERRUPT_STATUS_2); STOP_MAC_TIMER(); // stop Timer CLEAR_MAC_TIMER_INTERRUPT(); // clear flag CLEAR_MAC_EXT_INTERRUPT(); #ifndef B1_ONLY if(EZMacProReg.name.DTR == 0)//if rev V2 chip is used // this register setting is need for good current consumption in Idle mode (only rev V2) timerIntSpiWriteReg (SI4432_CRYSTAL_OSCILLATOR_CONTROL_TEST, SI4432_BUFOVR); #endif//B1_ONLY break; default: break; } // end switch }
void timerIntTX_StateMachine (U8 state) { #ifdef TRANSCEIVER_OPERATION U32 timeout; #endif//TRANSCEIVER_OPERATION #ifdef ANTENNA_DIVERSITY_ENABLED #ifndef B1_ONLY U8 temp8; #endif//B1_ONLY #endif//ANTENNA_DIVERSITY_ENABLED switch (state) { #ifdef TRANSCEIVER_OPERATION case TX_STATE_LBT_START_LISTEN: if(BusyLBT == 0) {//the channel was free during the first 0.5ms ChannelOccupiedInStartPeriod = 0; // start timer with fix 4.5ms timeout timerIntTimeout(LBT_FIXED_TIME_4500US); // go to the next state EZMacProReg.name.MSR = TX_STATE_BIT | TX_STATE_LBT_LISTEN; // disable the reciever timerIntSetFunction1(SI4432_XTON); // enable the receiver again timerIntSetFunction1( SI4432_RXON|SI4432_XTON); ENABLE_MAC_TIMER_INTERRUPT(); } else {//the channnel was busy during the first 0.5ms BusyLBT = 0; ChannelOccupiedInStartPeriod = 1; ChannelOccupiedCounter = 0; // start timer with fix 1ms timeout timerIntTimeout(LBT_FIXED_TIME_1000US); //go to the next state EZMacProReg.name.MSR = TX_STATE_BIT | TX_STATE_LBT_LISTEN; // disable the reciever timerIntSetFunction1(SI4432_XTON); // enable the receiver again timerIntSetFunction1( SI4432_RXON|SI4432_XTON); ENABLE_MAC_TIMER_INTERRUPT(); } break; case TX_STATE_LBT_LISTEN: if (ChannelOccupiedInStartPeriod == 0) {//the channel was free during the 0.5ms start period if(BusyLBT == 0) {// LBT passed, channel should be clear in the fix 4.5ms period //disable the receiver timerIntSetFunction1(SI4432_XTON); // clear enable 2 interrupt timerIntSetEnable2(0x00); // enable ENPKSENT bit timerIntSpiWriteReg(SI4432_INTERRUPT_ENABLE_1, SI4432_ENPKSENT); // enable TX timerIntSetFunction1( SI4432_TXON|SI4432_XTON); // start timer with transmit packet timeout timerIntTimeout(TimeoutTX_Packet); //go to the next state EZMacProReg.name.MSR = TX_STATE_BIT | TX_STATE_WAIT_FOR_TX; ENABLE_MAC_TIMER_INTERRUPT(); } else {//the channel was busy during the 4.5ms BusyLBT = 0; // multiple by fixed plus random number timeout = LBT_FIXED_TIME_5000US + TimeoutLBTI * (U32)(timerIntRandom()); // start timer with timeout timerIntTimeout(timeout); //go to the next state EZMacProReg.name.MSR = TX_STATE_BIT | TX_STATE_LBT_RANDOM_LISTEN; // disable the reciever timerIntSetFunction1(SI4432_XTON); // enable the receiver again timerIntSetFunction1( SI4432_RXON|SI4432_XTON); ENABLE_MAC_TIMER_INTERRUPT(); } } else {//the channel was busy during the 0.5ms start period if(BusyLBT == 0) {// LBT passed, channel should be clear in the fix 1ms period // multiple by fixed plus random number timeout = LBT_FIXED_TIME_5000US + TimeoutLBTI * (U32)(timerIntRandom()); // start timer with timeout timerIntTimeout(timeout); //go to the next state EZMacProReg.name.MSR = TX_STATE_BIT | TX_STATE_LBT_RANDOM_LISTEN; ENABLE_MAC_TIMER_INTERRUPT(); } else {//the channel was busy in the fix 1ms period if (ChannelOccupiedCounter < 9) { BusyLBT = 0; ChannelOccupiedCounter++; // start timer with fix 1ms timeout timerIntTimeout(LBT_FIXED_TIME_1000US); // go to the next state EZMacProReg.name.MSR = TX_STATE_BIT | TX_STATE_LBT_LISTEN; // disable the reciever timerIntSetFunction1(SI4432_XTON); // enable the receiver again timerIntSetFunction1( SI4432_RXON|SI4432_XTON); ENABLE_MAC_TIMER_INTERRUPT(); } else {//the channel was busy during the 10*1ms BusyLBT = 0; EZMacProLBT_Retrys++; if(EZMacProLBT_Retrys < MAX_LBT_RETRIES) {//the channel was busy and the retries didn't reach the maximum value // disable the reciever timerIntSetFunction1(SI4432_XTON); // start timer with fix ETSI timeout timerIntTimeout(TIMEOUT_LBTI_ETSI); // go to the next state EZMacProReg.name.MSR = TX_STATE_BIT | TX_STATE_LBT_START_LISTEN; ENABLE_MAC_TIMER_INTERRUPT(); // enable the receiver again timerIntSetFunction1( SI4432_RXON|SI4432_XTON); } else {//the channel was busy and the retries reach the maximum value //DISABLE_MAC_INTERRUPTS(); //disable the receiver timerIntSetFunction1(SI4432_XTON); //go to the next state EZMacProReg.name.MSR = TX_STATE_BIT | TX_ERROR_CHANNEL_BUSY; #ifdef FOUR_CHANNEL_IS_USED //increment error counter timerIntIncrementError(EZMAC_PRO_ERROR_CHANNEL_BUSY); #endif //FOUR_CHANNEL_IS_USED //call the LBT error callback function EZMacPRO_LBTTimeout(); } } } } break; case TX_STATE_LBT_RANDOM_LISTEN: if(BusyLBT == 0) {// the channel was free during the 5ms + random period //disable the receiver timerIntSetFunction1(SI4432_XTON); // clear enable 2 interrupt timerIntSetEnable2(0x00); // enable ENPKSENT bit timerIntSpiWriteReg(SI4432_INTERRUPT_ENABLE_1, SI4432_ENPKSENT); // enable TX timerIntSetFunction1( SI4432_TXON|SI4432_XTON); // start timer with transmit packet timeout timerIntTimeout(TimeoutTX_Packet); //go to the next state EZMacProReg.name.MSR = TX_STATE_BIT | TX_STATE_WAIT_FOR_TX; ENABLE_MAC_TIMER_INTERRUPT(); } else {//the channel was busy during the 5ms + random period BusyLBT = 0; EZMacProLBT_Retrys++; if(EZMacProLBT_Retrys < MAX_LBT_RETRIES) {//the channel was busy and the retries didn't reach the maximum value // disable the reciever timerIntSetFunction1(SI4432_XTON); // start timer with fix ETSI timeout timerIntTimeout(TIMEOUT_LBTI_ETSI); // go to the next state EZMacProReg.name.MSR = TX_STATE_BIT | TX_STATE_LBT_START_LISTEN; ENABLE_MAC_TIMER_INTERRUPT(); // enable the receiver again timerIntSetFunction1( SI4432_RXON|SI4432_XTON); } else {//the channel was busy and the retries reach the maximum value //disable the receiver timerIntSetFunction1(SI4432_XTON); //go to the next state EZMacProReg.name.MSR = TX_STATE_BIT | TX_ERROR_CHANNEL_BUSY; #ifdef FOUR_CHANNEL_IS_USED //increment error counter timerIntIncrementError(EZMAC_PRO_ERROR_CHANNEL_BUSY); #endif //FOUR_CHANNEL_IS_USED //call LBT error callback function EZMacPRO_LBTTimeout(); } } break; #endif//TRANSCEIVER_OPERATION case TX_STATE_WAIT_FOR_TX: // TX transmit error - no ipksent interrupt before timeout // This indicates a problem with the hardware or timeout //if there is a TX error then switch back the internal antenna diversity algorthm #ifdef ANTENNA_DIVERSITY_ENABLED #ifndef B1_ONLY //if revision V2 or A0 chip is used if ((EZMacProReg.name.DTR == 0x00) || (EZMacProReg.name.DTR == 0x01)) { //switch ON the internal algorithm temp8 = timerIntSpiReadReg(SI4432_OPERATING_AND_FUNCTION_CONTROL_2); timerIntSpiWriteReg (SI4432_OPERATING_AND_FUNCTION_CONTROL_2, temp8 | 0x80); //the gpios control the rf chip automatically timerIntSpiWriteReg(SI4432_GPIO1_CONFIGURATION, 0x17); timerIntSpiWriteReg(SI4432_GPIO2_CONFIGURATION, 0x18); } #endif//B1_ONLY #endif//ANTENNA_DIVERSITY_ENABLED // DISABLE_MAC_INTERRUPTS(); // clear EX0 & ET0 // STOP_MAC_TIMER(); // stop Timer // CLEAR_MAC_TIMER_INTERRUPT(); // clear flag // CLEAR_MAC_EXT_INTERRUPT(); //go to the TX ERROR STATE EZMacProReg.name.MSR = TX_STATE_BIT | TX_ERROR_STATE; //Call the Error state entered callback. EZMacPRO_StateErrorEntered(); break; #ifdef EXTENDED_PACKET_FORMAT //#ifndef TRANSMITTER_ONLY_OPERATION #ifdef TRANSCEIVER_OPERATION case TX_STATE_WAIT_FOR_ACK: DISABLE_MAC_INTERRUPTS(); // clear EX0 & ET0 //disbale the interrupts timerIntSpiWriteReg( SI4432_INTERRUPT_ENABLE_1, 0x00); timerIntSetEnable2(0x00); //clear interrupts timerIntSpiReadReg(SI4432_INTERRUPT_STATUS_1); timerIntSpiReadReg(SI4432_INTERRUPT_STATUS_2); //disable the receiver timerIntSetFunction1(SI4432_XTON); // //go to TX ERROR NO ACK state // EZMacProReg.name.MSR = TX_STATE_BIT | TX_ERROR_NO_ACK; //call the no ack callback function EZMacPRO_AckTimeout(); // all done use SECR to determine next state timerIntGotoNextStateUsingSECR(1); break; //#endif//TRANSMITTER_ONLY_OPERATION #endif//TRANSCEIVER_OPERATION #endif//EXTENDED_PACKET_FORMAT case TX_ERROR_STATE: DISABLE_MAC_INTERRUPTS(); // clear EX0 & ET0 // disable all Si443x interrupt sources timerIntSpiWriteReg(SI4432_INTERRUPT_ENABLE_1, 0x00); timerIntSetEnable2(0x00); // clear interrupts timerIntSpiReadReg(SI4432_INTERRUPT_STATUS_1); timerIntSpiReadReg(SI4432_INTERRUPT_STATUS_2); STOP_MAC_TIMER(); // stop Timer CLEAR_MAC_TIMER_INTERRUPT(); // clear flag CLEAR_MAC_EXT_INTERRUPT(); #ifndef B1_ONLY if(EZMacProReg.name.DTR == 0)//if rev V2 chip is used // this register setting is need for good current consumption in Idle mode (only rev V2) timerIntSpiWriteReg (SI4432_CRYSTAL_OSCILLATOR_CONTROL_TEST, SI4432_BUFOVR); #endif break; #ifdef TRANSCEIVER_OPERATION case TX_ERROR_CHANNEL_BUSY: break; #endif //TRANSCEIVER_OPERATION } // end switch }