// send data extern bool phy_tx_data(phy_tx_cfg_t* cfg) { //TODO Return error if fec not enabled but requested #ifdef D7_PHY_USE_FEC if (fec) { //Initialize fec encoding fec_init_encode(cfg->data); //Configure length settings set_length_infinite(true); fec_set_length(cfg->length); remainingBytes = ((cfg->length & 0xFE) + 2) << 1; WriteSingleReg(PKTLEN, (uint8_t)(remainingBytes & 0x00FF)); } else { #endif //Set buffer position bufferPosition = cfg->data; //Configure length settings set_length_infinite(false); remainingBytes = cfg->length; WriteSingleReg(PKTLEN, (uint8_t)remainingBytes); #ifdef D7_PHY_USE_FEC } #endif //Write initial data to txfifo tx_data_isr(); //Configure txfifo threshold WriteSingleReg(FIFOTHR, RADIO_FIFOTHR_FIFO_THR_17_48); //Enable interrupts radioClearInterruptPendingLines(); phy_set_gdo_values(GDOLine2, GDO_EDGE_TXBelowThresh, GDO_SETTING_TXBelowThresh); // phy_set_gdo_values(GDOLine2, GDO_EDGE_TXUnderflow, GDO_SETTING_TXUnderflow); phy_set_gdo_values(GDOLine0, GDO_EDGE_EndOfPacket, GDO_SETTING_EndOfPacket); radioEnableGDO2Interrupt(); radioEnableGDO0Interrupt(); //Start transmitting Strobe(RF_STX); return true; }
// ************************************************************************************************* // @fn Strobe // @brief Send command to radio. // @param unsigned char strobe Command to radio // @return statusByte Radio core status // ************************************************************************************************* unsigned char Strobe(unsigned char strobe) { u8 statusByte = 0; u16 int_state, gdo_state; // Check for valid strobe command if ((strobe == 0xBD) || ((strobe > RF_SRES) && (strobe < RF_SNOP))) { ENTER_CRITICAL_SECTION(int_state); // Clear the Status read flag RF1AIFCTL1 &= ~(RFSTATIFG); // Wait for radio to be ready for next instruction while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Write the strobe instruction if ((strobe > RF_SRES) && (strobe < RF_SNOP)) { gdo_state = ReadSingleReg(IOCFG2); // buffer IOCFG2 state WriteSingleReg(IOCFG2, 0x29); // c-ready to GDO2 RF1AINSTRB = strobe; if ((RF1AIN & 0x04) == 0x04) // chip at sleep mode { if ((strobe == RF_SXOFF) || (strobe == RF_SPWD) || (strobe == RF_SWOR)) { } else { while ((RF1AIN & 0x04) == 0x04) ; // c-ready ? __delay_cycles(9800); // Delay for ~810usec at 12MHz CPU clock } } WriteSingleReg(IOCFG2, gdo_state); // restore IOCFG2 setting } else // chip active mode { RF1AINSTRB = strobe; } statusByte = RF1ASTATB; while (!(RF1AIFCTL1 & RFSTATIFG)) ; EXIT_CRITICAL_SECTION(int_state); } return statusByte; }
void RADIOClass::SendData(byte *txBuffer,byte size) { WriteSingleReg(RADIO_TXFIFO,size); WriteBurstReg(RADIO_TXFIFO,txBuffer,size); //write data to send Strobe(RADIO_STX); //start send while (!digitalRead(GDO0)); // Wait for GDO0 to be set -> sync transmitted while (digitalRead(GDO0)); // Wait for GDO0 to be cleared -> end of packet Strobe(RADIO_SFTX); //flush TXfifo }
// ***************************************************************************** // @fn Strobe // @brief Send a command strobe to the radio. // @param unsigned char strobe The strobe command to be sent // @return unsigned char statusByte The status byte that follows the strobe // ***************************************************************************** unsigned char Strobe(unsigned char strobe) { unsigned char statusByte = 0; unsigned int gdo_state; // Check for valid strobe command if((strobe == 0xBD) || ((strobe >= RF_SRES) && (strobe <= RF_SNOP))) { // Clear the Status read flag RF1AIFCTL1 &= ~(RFSTATIFG); // Wait for radio to be ready for next instruction while( !(RF1AIFCTL1 & RFINSTRIFG)); // Write the strobe instruction if ((strobe > RF_SRES) && (strobe < RF_SNOP)) { gdo_state = ReadSingleReg(IOCFG2); // buffer IOCFG2 state WriteSingleReg(IOCFG2, 0x29); // chip-ready to GDO2 RF1AINSTRB = strobe; if ( (RF1AIN&0x04)== 0x04 ) // chip at sleep mode { if ( (strobe == RF_SXOFF) || (strobe == RF_SPWD) || (strobe == RF_SWOR) ) { } else { while ((RF1AIN&0x04)== 0x04); // chip-ready ? // Delay for ~810usec at 1.05MHz CPU clock, see Section 22.3.3.7 // Radio Control – Crystal Control of the CC430 User’s Guide (SLAU 259)” __delay_cycles(850); } } WriteSingleReg(IOCFG2, gdo_state); // restore IOCFG2 setting while( !(RF1AIFCTL1 & RFSTATIFG) ); } else // chip active mode (SRES) { RF1AINSTRB = strobe; } statusByte = RF1ASTATB; } return statusByte; }
//------------------------------------------------------------------------------ // void pktTxHandler(void) // // DESCRIPTION: // This function is called every time a timer interrupt occurs. The function starts // by getting the status byte. Every time the status byte indicates that there // is free space in the TX FIFO, bytes are taken from txBuffer and written to // the TX FIFO until the whole packet is written or the TXFIFO has underflowed. // See the EM430F5137RF900 RF Examples User Manual for a flow chart describing // this function. //------------------------------------------------------------------------------ void pktTxHandler(void) { unsigned char freeSpaceInFifo; unsigned char TxStatus; // Which state? TxStatus = Strobe(RF_SNOP); switch (TxStatus & CC430_STATE_MASK) { case CC430_STATE_TX: // If there's anything to transfer.. if (freeSpaceInFifo = MIN(txBytesLeft, TxStatus & CC430_FIFO_BYTES_AVAILABLE_MASK)) { txBytesLeft -= freeSpaceInFifo; while(freeSpaceInFifo--) { WriteSingleReg(TXFIFO, TxBuffer[txPosition]); txPosition++; } if(!txBytesLeft) { RF1AIES |= BIT9; // End-of-packet TX interrupt RF1AIFG &= ~BIT9; // clear RFIFG9 while(!(RF1AIFG & BIT9)); // poll RFIFG9 for TX end-of-packet RF1AIES &= ~BIT9; // End-of-packet TX interrupt RF1AIFG &= ~BIT9; // clear RFIFG9 transmitting = 0; packetTransmit = 1; } } break; case CC430_STATE_TX_UNDERFLOW: Strobe(RF_SFTX); // Flush the TX FIFO __no_operation(); // No break here! default: if(!packetTransmit) packetTransmit = 1; if (transmitting) { if ((TxStatus & CC430_STATE_MASK) == CC430_STATE_IDLE) { transmitting = 0; } } break; } } // pktTxHandler
// ************************************************************************************************* // @fn sx_bluerobin // @brief BlueRobin direct function. Button UP connects/disconnects with sender unit. // @param u8 line LINE1 // @return none // ************************************************************************************************* void sx_bluerobin(u8 line) { u8 stop = 0; // Exit if battery voltage is too low for radio operation if (sys.flag.low_battery) return; // Exit if SimpliciTI stack is active if (is_rf()) return; // UP: connect / disconnect transmitter if(button.flag.up) { if (sBlueRobin.state == BLUEROBIN_OFF) { // Init BlueRobin timer and radio open_radio(); // Initialize BR library BRRX_Init_v(); // Set BR data transmission properties BRRX_SetPowerdownDelay_v(10); // Power down channel after 10 consecutive lost data packets (~9 seconds) BRRX_SetSearchTimeout_v(8); // Stop searching after 8 seconds // Sensitivity in learn mode reduced --> connect only to close transmitters // Skip this part if chest strap id was set in a previous learn mode run #if REMEMBER_TX_ID == TRUE if (sBlueRobin.cs_id == 0) BRRX_SetSignalLevelReduction_v(5); #else // Forget previously learned transmitter ID and connect to next close transmitter sBlueRobin.cs_id = 0; BRRX_SetSignalLevelReduction_v(5); #endif // Apply frequency offset compensation to radio register FSCTRL0 // If calibration memory was erased, rf_frequoffset defaults to 0x00 and has no effect WriteSingleReg(FSCTRL0, rf_frequoffset); // New state is SEARCH sBlueRobin.state = BLUEROBIN_SEARCHING; // Blink RF icon to show searching display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); // Turn on radio and establish connection if channel not already started if (BRRX_GetState_t(HR_CHANNEL) == TX_OFF) { // Start in learn mode (connect to closest heart rate transmitter) BRRX_SetID_v(HR_CHANNEL, sBlueRobin.cs_id); BRRX_Start_v(HR_CHANNEL); // Wait until learning phase is over while (BRRX_GetState_t(HR_CHANNEL)==TX_SEARCH) { Timer0_A4_Delay(CONV_MS_TO_TICKS(200)); } } // Check if connection attempt was successful if (BRRX_GetState_t(HR_CHANNEL)==TX_ACTIVE) { // Successfully connected to transmitter sBlueRobin.state = BLUEROBIN_CONNECTED; // When in learn mode, copy chest strap ID if (sBlueRobin.cs_id == 0) { sBlueRobin.cs_id = BRRX_GetID_u32(HR_CHANNEL); } // Show steady RF icon to indicate established connection display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF); display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF); display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF); // Show blinking icon display_symbol(LCD_ICON_HEART, SEG_ON_BLINK_ON); } else // Error -> Shutdown connection { stop = 1; } } else if (sBlueRobin.state == BLUEROBIN_CONNECTED) { // Shutdown connection stop = 1; } } // Shutdown connection if (stop) { stop_bluerobin(); } }
// ************************************************************************************************* // @fn start_bluerobin // @brief Start BlueRobin stack and search for a transmitter. // @param none // @return 0 = no transmitter found, 1 = connected to a transmitter // ************************************************************************************************* u8 start_bluerobin(void) { u8 timeout, i; // Init BlueRobin timer and radio // Enable high current mode open_radio(); // Initialize BR library BRRX_Init_v(); // Set BR data transmission properties BRRX_SetPowerdownDelay_v(10); // Power down channel after 10 consecutive lost data packets (~9 // seconds) BRRX_SetSearchTimeout_v(6); // Stop searching after 8 seconds // Sensitivity in learn mode reduced --> connect only to close transmitters // Skip this part if chest strap id was set in a previous learn mode run #if REMEMBER_TX_ID == TRUE if (sBlueRobin.cs_id == 0) BRRX_SetSignalLevelReduction_v(5); #else // Forget previously learned transmitter ID and connect to next close transmitter sBlueRobin.cs_id = 0; BRRX_SetSignalLevelReduction_v(5); #endif // Apply frequency offset compensation to radio register FSCTRL0 // If calibration memory was erased, rf_frequoffset defaults to 0x00 and has no effect WriteSingleReg(FSCTRL0, rf_frequoffset); // New state is SEARCH sBlueRobin.state = BLUEROBIN_SEARCHING; // Blink RF icon to show searching display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); // Turn on radio and establish connection if channel not already started if (BRRX_GetState_t(HR_CHANNEL) == TX_OFF) { // Start in learn mode (connect to closest heart rate transmitter) BRRX_SetID_v(HR_CHANNEL, sBlueRobin.cs_id); BRRX_Start_v(HR_CHANNEL); // Wait until learning phase is over, additional timeout prevents race condition if hardware // works incorrect timeout = 40; while ((BRRX_GetState_t(HR_CHANNEL) == TX_SEARCH) && (timeout-- > 0)) { Timer0_A4_Delay(CONV_MS_TO_TICKS(200)); } // Timeout? if (timeout == 0) { display_chars(LCD_SEG_L1_3_0, (u8 *) "FAIL", SEG_ON); for (i = 0; i < 4; i++) Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); } } // Check if connection attempt was successful if (BRRX_GetState_t(HR_CHANNEL) == TX_ACTIVE) { // Successfully connected to transmitter sBlueRobin.state = BLUEROBIN_CONNECTED; // When in learn mode, copy chest strap ID if (sBlueRobin.cs_id == 0) sBlueRobin.cs_id = BRRX_GetID_u32(HR_CHANNEL); // Show steady RF icon to indicate established connection display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF); display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF); display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF); // Show blinking icon display_symbol(LCD_ICON_HEART, SEG_ON_BLINK_ON); return (1); } else // Error -> Shutdown connection { // Clear RF icon display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); return (0); } }
void RADIOClass::RegConfig(void) { WriteSingleReg(RADIO_IOCFG2, 0x29 ); // GDO2 output pin configuration WriteSingleReg(RADIO_IOCFG1, 0x2E ); // GDO1 output pin configuration WriteSingleReg(RADIO_IOCFG0, 0x06 ); // GDO0 output pin configuration WriteSingleReg(RADIO_FIFOTHR, 0x07 ); // RX FIFO and TX FIFO thresholds WriteSingleReg(RADIO_SYNC1, 0xD3 ); // Sync word, high INT8U WriteSingleReg(RADIO_SYNC0, 0x91 ); // Sync word, low INT8U WriteSingleReg(RADIO_PKTLEN, 0x3D ); // Packet length WriteSingleReg(RADIO_PKTCTRL1, 0x04 ); // Packet automation control WriteSingleReg(RADIO_PKTCTRL0, 0x05 ); // Packet automation control WriteSingleReg(RADIO_ADDR, 0x00 ); // Device address WriteSingleReg(RADIO_CHANNR, 0x00 ); // Channel number WriteSingleReg(RADIO_FSCTRL1, 0x0C ); // Frequency synthesizer control WriteSingleReg(RADIO_FSCTRL0, 0x00 ); // Frequency synthesizer control WriteSingleReg(RADIO_FREQ2, 0x21 ); // Frequency control word, high INT8U WriteSingleReg(RADIO_FREQ1, 0x6B ); // Frequency control word, middle INT8U WriteSingleReg(RADIO_FREQ0, 0x24 ); // Frequency control word, low INT8U WriteSingleReg(RADIO_MDMCFG4, 0x15 ); // Modem configuration WriteSingleReg(RADIO_MDMCFG3, 0x75 ); // Modem configuration WriteSingleReg(RADIO_MDMCFG2, 0x03 ); // Modem configuration WriteSingleReg(RADIO_MDMCFG1, 0x21 ); // Modem configuration WriteSingleReg(RADIO_MDMCFG0, 0xE5 ); // Modem configuration WriteSingleReg(RADIO_DEVIATN, 0x71 ); // Modem deviation setting WriteSingleReg(RADIO_MCSM2, 0x07 ); // Main Radio Control State Machine configuration WriteSingleReg(RADIO_MCSM1, 0x30 ); // Main Radio Control State Machine configuration WriteSingleReg(RADIO_MCSM0, 0x18 ); // Main Radio Control State Machine configuration WriteSingleReg(RADIO_FOCCFG, 0x1D ); // Frequency Offset Compensation configuration WriteSingleReg(RADIO_BSCFG, 0x1C ); // Bit Synchronization configuration WriteSingleReg(RADIO_AGCCTRL2, 0x47 ); // AGC control WriteSingleReg(RADIO_AGCCTRL1, 0x40 );// AGC control WriteSingleReg(RADIO_AGCCTRL0, 0xB0 ); // AGC control WriteSingleReg(RADIO_WOREVT1, 0x00 ); // High INT8U Event 0 timeout WriteSingleReg(RADIO_WOREVT0, 0x00 ); // Low INT8U Event 0 timeout WriteSingleReg(RADIO_WORCTRL, 0xF8 ); // Wake On Radio control WriteSingleReg(RADIO_FREND1, 0xB7 ); // Front end RX configuration WriteSingleReg(RADIO_FREND0, 0x10 ); // Front end TX configuration WriteSingleReg(RADIO_FSCAL3, 0xE9 ); // Frequency synthesizer calibration WriteSingleReg(RADIO_FSCAL2, 0x2A ); // Frequency synthesizer calibration WriteSingleReg(RADIO_FSCAL1, 0x00 ); // Frequency synthesizer calibration WriteSingleReg(RADIO_FSCAL0, 0x1F ); // Frequency synthesizer calibration WriteSingleReg(RADIO_RCCTRL1, 0x00 ); // RC oscillator configuration WriteSingleReg(RADIO_RCCTRL0, 0x00 );// RC oscillator configuration WriteSingleReg(RADIO_FSTEST, 0x59 ); // Frequency synthesizer calibration control WriteSingleReg(RADIO_PTEST, 0x7F ); // Production test WriteSingleReg(RADIO_AGCTEST, 0x3F ); // AGC test WriteSingleReg(RADIO_TEST2, 0x88 ); // Various test settings WriteSingleReg(RADIO_TEST1, 0x31 ); // Various test settings WriteSingleReg(RADIO_TEST0, 0x09 ); // Various test settings }
// ***************************************************************************** // @fn WriteRfSettings // @brief Write the minimum set of RF configuration register settings // @param RF_SETTINGS *pRfSettings Pointer to the structure that holds the rf settings // @return none // ***************************************************************************** void WriteRfSettings(RF_SETTINGS *pRfSettings) { WriteSingleReg(FSCTRL1, pRfSettings->fsctrl1); WriteSingleReg(FSCTRL0, pRfSettings->fsctrl0); WriteSingleReg(FREQ2, pRfSettings->freq2); WriteSingleReg(FREQ1, pRfSettings->freq1); WriteSingleReg(FREQ0, pRfSettings->freq0); WriteSingleReg(MDMCFG4, pRfSettings->mdmcfg4); WriteSingleReg(MDMCFG3, pRfSettings->mdmcfg3); WriteSingleReg(MDMCFG2, pRfSettings->mdmcfg2); WriteSingleReg(MDMCFG1, pRfSettings->mdmcfg1); WriteSingleReg(MDMCFG0, pRfSettings->mdmcfg0); WriteSingleReg(CHANNR, pRfSettings->channr); WriteSingleReg(DEVIATN, pRfSettings->deviatn); WriteSingleReg(FREND1, pRfSettings->frend1); WriteSingleReg(FREND0, pRfSettings->frend0); WriteSingleReg(MCSM0 , pRfSettings->mcsm0); WriteSingleReg(FOCCFG, pRfSettings->foccfg); WriteSingleReg(BSCFG, pRfSettings->bscfg); WriteSingleReg(AGCCTRL2, pRfSettings->agcctrl2); WriteSingleReg(AGCCTRL1, pRfSettings->agcctrl1); WriteSingleReg(AGCCTRL0, pRfSettings->agcctrl0); WriteSingleReg(FSCAL3, pRfSettings->fscal3); WriteSingleReg(FSCAL2, pRfSettings->fscal2); WriteSingleReg(FSCAL1, pRfSettings->fscal1); WriteSingleReg(FSCAL0, pRfSettings->fscal0); WriteSingleReg(FSTEST, pRfSettings->fstest); WriteSingleReg(TEST2, pRfSettings->test2); WriteSingleReg(TEST1, pRfSettings->test1); WriteSingleReg(TEST0, pRfSettings->test0); WriteSingleReg(FIFOTHR, pRfSettings->fifothr); WriteSingleReg(IOCFG2, pRfSettings->iocfg2); WriteSingleReg(IOCFG0, pRfSettings->iocfg0); WriteSingleReg(PKTCTRL1, pRfSettings->pktctrl1); WriteSingleReg(PKTCTRL0, pRfSettings->pktctrl0); WriteSingleReg(ADDR, pRfSettings->addr); WriteSingleReg(PKTLEN, pRfSettings->pktlen); WriteSingleReg(SYNC1, RF_SYNC1); // 同步字高字节 WriteSingleReg(SYNC0, RF_SYNC0); // 同步字低字节 }
void MCP23017::SetIntPortBBank1(uint8_t Iocon, uint8_t Intcon, uint8_t Defval, uint8_t GpintEn, uint8_t i2caddr) { WriteSingleReg(MCP23017_BNK1_IOCONB, Iocon, i2caddr); WriteSingleReg(MCP23017_BNK1_INTCONB, Intcon, i2caddr); WriteSingleReg(MCP23017_BNK1_DEFVALB, Defval, i2caddr); WriteSingleReg(MCP23017_BNK1_GPINTENB, GpintEn, i2caddr); }
void MCP23017::SetIntPortABank0(uint8_t Iocon, uint8_t Intcon, uint8_t Defval, uint8_t GpintEn, uint8_t i2caddr) { WriteSingleReg(MCP23017_BNK0_IOCONA, Iocon, i2caddr); WriteSingleReg(MCP23017_BNK0_INTCONA, Intcon, i2caddr); WriteSingleReg(MCP23017_BNK0_DEFVALA, Defval, i2caddr); WriteSingleReg(MCP23017_BNK0_GPINTENA, GpintEn, i2caddr); }
static void phy_set_gdo_values(GDOLine gdoLine, GDOEdge gdoEdge, uint8_t gdoValue) { WriteSingleReg(gdoLine, gdoValue | gdoEdge); }
void rx_data_isr() { //Read number of bytes in RXFIFO uint8_t rxBytes = ReadSingleReg(RXBYTES); #ifdef LOG_PHY_ENABLED log_print_stack_string(LOG_PHY, "rx_data_isr (%d bytes received)", rxBytes); #endif #ifdef D7_PHY_USE_FEC if(fec) { uint8_t fecbuffer[4]; //If length is not set get the length from RXFIFO and set PKTLEN if (packetLength == 0) { ReadBurstReg(RXFIFO, fecbuffer, 4); fec_decode(fecbuffer); fec_set_length(*buffer); packetLength = ((*buffer & 0xFE) + 2) << 1; remainingBytes = packetLength - 4; WriteSingleReg(PKTLEN, (uint8_t)(packetLength & 0x00FF)); WriteSingleReg(FIFOTHR, RADIO_FIFOTHR_FIFO_THR_17_48); rxBytes -= 4; } //If remaining bytes is equal or less than 255 - fifo size, set length to fixed if(remainingBytes < 192) set_length_infinite(false); //Read data from buffer and decode while (rxBytes >= 4) { ReadBurstReg(RXFIFO, fecbuffer, 4); if(fec_decode(fecbuffer) == false) break; remainingBytes -= 4; rxBytes -= 4; } } else { #endif //If length is not set get the length from RXFIFO and set PKTLEN if (packetLength == 0) { packetLength = ReadSingleReg(RXFIFO); WriteSingleReg(PKTLEN, packetLength); WriteSingleReg(FIFOTHR, RADIO_FIFOTHR_FIFO_THR_17_48); remainingBytes = packetLength - 1; bufferPosition[0] = packetLength; bufferPosition++; rxBytes--; #ifdef LOG_PHY_ENABLED log_print_stack_string(LOG_PHY, "rx_data_isr getting packetLength (%d)", packetLength); #endif } //Never read the entire buffer as long as more data is going to be received if (remainingBytes > rxBytes) { rxBytes--; } else { rxBytes = remainingBytes; } //Read data from buffer ReadBurstReg(RXFIFO, bufferPosition, rxBytes); remainingBytes -= rxBytes; bufferPosition += rxBytes; #ifdef D7_PHY_USE_FEC } #endif //When all data has been received read rssi and lqi value and set packetreceived flag if(remainingBytes == 0) { rx_data.rssi = calculate_rssi(ReadSingleReg(RXFIFO)); rx_data.lqi = ReadSingleReg(RXFIFO) & 0x7F; rx_data.length = *buffer; rx_data.data = buffer; #ifdef LOG_PHY_ENABLED log_print_stack_string(LOG_PHY, "rx_data_isr packet received"); #endif } #ifdef LOG_PHY_ENABLED log_print_stack_string(LOG_PHY, "rx_data_isr 1"); #endif }
bool phy_rx(phy_rx_cfg_t* cfg) { #ifdef LOG_PHY_ENABLED log_print_stack_string(LOG_PHY, "phy_rx"); #endif RadioState current_state = get_radiostate(); if(current_state != Idle && current_state != Receive) { #ifdef LOG_PHY_ENABLED log_print_stack_string(LOG_PHY, "PHY Cannot RX, PHy not idle"); #endif return false; } //Set radio state state = Receive; //Flush the txfifo Strobe(RF_SIDLE); Strobe(RF_SFRX); //Set configuration if (!phy_translate_and_set_settings(cfg->spectrum_id, cfg->sync_word_class)) return false; set_timeout(cfg->timeout); //TODO Return error if fec not enabled but requested #ifdef D7_PHY_USE_FEC if (fec) { //Disable hardware data whitening set_data_whitening(false); //Initialize fec encoding fec_init_decode(buffer); //Configure length settings set_length_infinite(true); if(cfg->length == 0) { packetLength = 0; remainingBytes = 0; WriteSingleReg(PKTLEN, 0xFF); WriteSingleReg(FIFOTHR, RADIO_FIFOTHR_FIFO_THR_61_4); } else { fec_set_length(cfg->length); packetLength = ((cfg->length & 0xFE) + 2) << 1; remainingBytes = packetLength; WriteSingleReg(PKTLEN, (uint8_t)(packetLength & 0x00FF)); WriteSingleReg(FIFOTHR, RADIO_FIFOTHR_FIFO_THR_17_48); } } else { #endif //Enable hardware data whitening set_data_whitening(true); //Set buffer position bufferPosition = buffer; //Configure length settings and txfifo threshold set_length_infinite(false); if(cfg->length == 0) { packetLength = 0; remainingBytes = 0; WriteSingleReg(PKTLEN, 0xFF); WriteSingleReg(FIFOTHR, RADIO_FIFOTHR_FIFO_THR_61_4); } else { packetLength = cfg->length; remainingBytes = packetLength; WriteSingleReg(PKTLEN, packetLength); WriteSingleReg(FIFOTHR, RADIO_FIFOTHR_FIFO_THR_17_48); } #ifdef D7_PHY_USE_FEC } #endif //TODO: set minimum sync word rss to scan minimum energy //Enable interrupts phy_set_gdo_values(GDOLine2, GDO_EDGE_RXFilled, GDO_SETTING_RXFilled); phy_set_gdo_values(GDOLine0, GDO_EDGE_EndOfPacket, GDO_SETTING_EndOfPacket); radioClearInterruptPendingLines(); radioEnableGDO2Interrupt(); radioEnableGDO0Interrupt(); //Start receiving Strobe(RF_SRX); return true; }
void it_rf_init(void) { // logic 0 and logic 1 power levels for OOK modulation #ifdef CONFIG_MOD_INTERTECHNO_PW uint8_t PATable[2] = { 0x00, it_pwr[it_pwr_level] }; #else uint8_t PATable[2] = { 0x00, INTERTECHNO_RF_POWER }; #endif ResetRadioCore(); // minimal register changes WriteSingleReg(IOCFG0, 0x06); //GDO0 Output Configuration WriteSingleReg(PKTLEN, INTERTECHNO_SEQ_SIZE*4); //Packet Length WriteSingleReg(PKTCTRL0, 0x00); //Packet Automation Control WriteSingleReg(FREQ2, 0x10); //Frequency Control Word, High Byte WriteSingleReg(FREQ1, 0xB0); //Frequency Control Word, Middle Byte WriteSingleReg(FREQ0, 0x71); //Frequency Control Word, Low Byte WriteSingleReg(MDMCFG4, 0x86); //Modem Configuration WriteSingleReg(MDMCFG3, 0x70); //Modem Configuration WriteSingleReg(MDMCFG2, 0x30); //Modem Configuration WriteSingleReg(MDMCFG1, 0x02); //Modem Configuration WriteSingleReg(MCSM1, 0x00); //Main Radio Control State Machine Configuration WriteSingleReg(MCSM0, 0x00); //Main Radio Control State Machine Configuration WriteSingleReg(FOCCFG, 0x76); //Frequency Offset Compensation Configuration WriteSingleReg(WOREVT1, 0x87); //High Byte Event0 Timeout WriteSingleReg(WOREVT0, 0x6B); //Low Byte Event0 Timeout WriteSingleReg(WORCTRL, 0xF8); //Wake On Radio Control WriteSingleReg(FREND0, 0x11); //Front End TX Configuration WriteSingleReg(TEST0, 0x09); //Various Test Settings WriteBurstPATable(&PATable[0], 2); }
// ************************************************************************************************* // @fn WriteSmartRFReg // @brief Writes all the Radio Settings to the Radio module // @param none // @return none // ************************************************************************************************* void WriteSmartRFReg(const u8 SmartRFSetting[][2], u8 size) { u8 i; for (i=0; i < (size); i++) WriteSingleReg(SmartRFSetting[i][0], SmartRFSetting[i][1]); }