/** * @brief Sets a TAL PIB attribute * * This function is called to set the transceiver information base * attributes. * * @param attribute TAL infobase attribute ID * @param value TAL infobase attribute value to be set * * @return MAC_UNSUPPORTED_ATTRIBUTE if the TAL info base attribute is not found * TAL_BUSY if the TAL is not in TAL_IDLE state. An exception is * macBeaconTxTime which can be accepted by TAL even if TAL is not * in TAL_IDLE state. * MAC_SUCCESS if the attempt to set the PIB attribute was successful * TAL_TRX_ASLEEP if trx is in SLEEP mode and access to trx is required */ retval_t tal_pib_set(uint8_t attribute, pib_value_t *value) { /* * Do not allow any changes while ED or TX is done. * We allow changes during RX, but it's on the user's own risk. */ #if (MAC_SCAN_ED_REQUEST_CONFIRM == 1) if (tal_state == TAL_ED_RUNNING) { ASSERT("TAL is busy" == 0); return TAL_BUSY; } #endif /* (MAC_SCAN_ED_REQUEST_CONFIRM == 1) */ /* * Distinguish between PIBs that need to be changed in trx directly * and those that are simple variable udpates. * Ensure that the transceiver is not in SLEEP. * If it is in SLEEP, change it to TRX_OFF. */ switch (attribute) { case macMaxFrameRetries: /* * The new PIB value is not immediately written to the * transceiver. This is done on a frame-by-frame base. */ tal_pib_MaxFrameRetries = value->pib_value_8bit; break; case macMaxCSMABackoffs: /* * The new PIB value is not immediately written to the * transceiver. This is done on a frame-by-frame base. */ tal_pib_MaxCSMABackoffs = value->pib_value_8bit; break; #ifdef BEACON_SUPPORT case macBattLifeExt: tal_pib_BattLifeExt = value->pib_value_bool; break; case macBeaconOrder: tal_pib_BeaconOrder = value->pib_value_8bit; break; case macSuperframeOrder: tal_pib_SuperFrameOrder = value->pib_value_8bit; break; case macBeaconTxTime: tal_pib_BeaconTxTime = value->pib_value_32bit; break; #endif /* BEACON_SUPPORT */ #ifdef PROMISCUOUS_MODE case macPromiscuousMode: tal_pib_PromiscuousMode = value->pib_value_8bit; if (tal_pib_PromiscuousMode) { tal_trx_wakeup(); /* Check if receive buffer is available or queue is not full. */ if (NULL == tal_rx_buffer) { set_trx_state(CMD_PLL_ON); tal_rx_on_required = true; } else { set_trx_state(CMD_RX_ON); } } else { set_trx_state(CMD_TRX_OFF); tal_rx_on_required = false; } break; #endif default: /* * Following PIBs require access to trx. * Therefore trx must be at least in TRX_OFF. */ if (tal_trx_status == TRX_SLEEP) { /* While trx is in SLEEP, register cannot be accessed. */ return TAL_TRX_ASLEEP; } switch (attribute) { case macMinBE: tal_pib_MinBE = value->pib_value_8bit; #ifndef REDUCED_PARAM_CHECK /* * macMinBE must not be larger than macMaxBE or calculation * of macMaxFrameWaitTotalTime will fail. */ if (tal_pib_MinBE > tal_pib_MaxBE) { tal_pib_MinBE = tal_pib_MaxBE; } #endif /* REDUCED_PARAM_CHECK */ pal_trx_bit_write(SR_MIN_BE, tal_pib_MinBE); break; case macPANId: tal_pib_PANId = value->pib_value_16bit; pal_trx_reg_write(RG_PAN_ID_0, (uint8_t)tal_pib_PANId); pal_trx_reg_write(RG_PAN_ID_1, (uint8_t)(tal_pib_PANId >> 8)); break; case macShortAddress: tal_pib_ShortAddress = value->pib_value_16bit; pal_trx_reg_write(RG_SHORT_ADDR_0, (uint8_t)tal_pib_ShortAddress); pal_trx_reg_write(RG_SHORT_ADDR_1, (uint8_t)(tal_pib_ShortAddress >> 8)); break; case phyCurrentChannel: if (tal_state != TAL_IDLE) { return TAL_BUSY; } if (tal_pib_CurrentPage == 5) { if (((uint32_t)TRX_SUPPORTED_CHANNELS_CHINA & ((uint32_t)0x01 << value->pib_value_8bit)) == false) { return MAC_INVALID_PARAMETER; } } else { if (((uint32_t)TRX_SUPPORTED_CHANNELS & ((uint32_t)0x01 << value->pib_value_8bit)) == false) { return MAC_INVALID_PARAMETER; } } { uint8_t previous_channel; tal_trx_status_t previous_trx_status = TRX_OFF; previous_channel = tal_pib_CurrentChannel; tal_pib_CurrentChannel = value->pib_value_8bit; /* * Set trx to "soft" off avoiding that ongoing * transaction (e.g. ACK) are interrupted. */ if (tal_trx_status != TRX_OFF) { previous_trx_status = RX_AACK_ON; /* any other than TRX_OFF state */ do { /* set TRX_OFF until it could be set; * trx might be busy */ } while (set_trx_state(CMD_TRX_OFF) != TRX_OFF); } /* Check if frequency band/modulation is changed. */ if (tal_pib_CurrentPage == 5) { pal_trx_bit_write(SR_CC_NUMBER, GET_CHINA_FREQ(tal_pib_CurrentChannel)); } else if ((tal_pib_CurrentChannel > 0) && (previous_channel > 0)) { pal_trx_bit_write(SR_CHANNEL, tal_pib_CurrentChannel); } else { uint8_t reg_value; /* Set modulation and channel */ apply_channel_page_configuration(tal_pib_CurrentPage); limit_tx_pwr(); reg_value = convert_phyTransmitPower_to_reg_value(tal_pib_TransmitPower); pal_trx_reg_write(RG_PHY_TX_PWR, reg_value); } /* Re-store previous trx state */ if (previous_trx_status != TRX_OFF) { /* Set to default state */ set_trx_state(CMD_RX_AACK_ON); } } break; case phyCurrentPage: if (tal_state != TAL_IDLE) { return TAL_BUSY; } else { uint8_t page; tal_trx_status_t previous_trx_status = TRX_OFF; bool ret_val; uint8_t reg_value; /* * Changing the channel, channel page or modulation * requires that TRX is in TRX_OFF. * Store current trx state and return to default state * after channel page has been set. */ if (tal_trx_status != TRX_OFF) { previous_trx_status = RX_AACK_ON; /* any other than TRX_OFF state */ do { /* set TRX_OFF until it could be set; * trx might be busy */ } while (set_trx_state(CMD_TRX_OFF) != TRX_OFF); } page = value->pib_value_8bit; ret_val = apply_channel_page_configuration(page); if (previous_trx_status != TRX_OFF) { /* Set to default state */ set_trx_state(CMD_RX_AACK_ON); } if (ret_val) { tal_pib_CurrentPage = page; } else { return MAC_INVALID_PARAMETER; } limit_tx_pwr(); reg_value = convert_phyTransmitPower_to_reg_value(tal_pib_TransmitPower); pal_trx_reg_write(RG_PHY_TX_PWR, reg_value); } break; case macMaxBE: tal_pib_MaxBE = value->pib_value_8bit; #ifndef REDUCED_PARAM_CHECK /* * macMinBE must not be larger than macMaxBE or calculation * of macMaxFrameWaitTotalTime will fail. */ if (tal_pib_MaxBE < tal_pib_MinBE) { tal_pib_MinBE = tal_pib_MaxBE; } #endif /* REDUCED_PARAM_CHECK */ pal_trx_bit_write(SR_MAX_BE, tal_pib_MaxBE); break; case phyTransmitPower: { uint8_t reg_value; tal_pib_TransmitPower = value->pib_value_8bit; /* Limit tal_pib_TransmitPower to max/min trx values */ limit_tx_pwr(); reg_value = convert_phyTransmitPower_to_reg_value(tal_pib_TransmitPower); pal_trx_reg_write(RG_PHY_TX_PWR, reg_value); } break; case phyCCAMode: tal_pib_CCAMode = value->pib_value_8bit; pal_trx_bit_write(SR_CCA_MODE, tal_pib_CCAMode); break; case macIeeeAddress: { uint8_t *ptr; tal_pib_IeeeAddress = value->pib_value_64bit; ptr = (uint8_t *)&tal_pib_IeeeAddress; for (uint8_t i = 0; i < 8; i++) { pal_trx_reg_write((RG_IEEE_ADDR_0 + i), *ptr); ptr++; } } break; case mac_i_pan_coordinator: tal_pib_PrivatePanCoordinator = value->pib_value_bool; pal_trx_bit_write(SR_AACK_I_AM_COORD, tal_pib_PrivatePanCoordinator); break; case macAckWaitDuration: /* * AT86RF212 does not support changing this value w.r.t. * compliance operation. */ return MAC_UNSUPPORTED_ATTRIBUTE; default: return MAC_UNSUPPORTED_ATTRIBUTE; } break; /* end of 'default' from 'switch (attribute)' */ } return MAC_SUCCESS; } /* tal_pib_set() */
/** * @brief Apply channel page configuartion to transceiver * * @param ch_page Channel page * * @return true if changes could be applied else false */ static bool apply_channel_page_configuration(uint8_t ch_page) { /* * Before updating the transceiver a number of TAL PIB attributes need * to be updated depending on the channel page. */ tal_pib_MaxFrameDuration = MAX_FRAME_DURATION; tal_pib_SHRDuration = NO_OF_SYMBOLS_PREAMBLE_SFD; tal_pib_SymbolsPerOctet = SYMBOLS_PER_OCTET; switch (ch_page) { case 0: /* BPSK */ pal_trx_bit_write(SR_BPSK_OQPSK, BPSK_MODE); pal_trx_bit_write(SR_GC_TX_OFFS, BPSK_TX_OFFSET); if (tal_pib_CurrentChannel == 0) { pal_trx_bit_write(SR_SUB_MODE, LOW_DATA_RATE); } else { pal_trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); pal_trx_bit_write(SR_OQPSK_SUB1_RC_EN, HALF_SINE_FILTERING); } // Compliant ACK timing pal_trx_bit_write(SR_AACK_ACK_TIME, AACK_ACK_TIME_12_SYMBOLS); tal_pib_SupportedChannels = TRX_SUPPORTED_CHANNELS; pal_trx_bit_write(SR_CC_BAND, 0); pal_trx_bit_write(SR_CHANNEL, tal_pib_CurrentChannel); break; case 2: /* O-QPSK */ pal_trx_bit_write(SR_BPSK_OQPSK, OQPSK_MODE); pal_trx_bit_write(SR_GC_TX_OFFS, OQPSK_TX_OFFSET); pal_trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_100_KBPS_OR_250_KBPS); if (tal_pib_CurrentChannel == 0) { pal_trx_bit_write(SR_SUB_MODE, LOW_DATA_RATE); } else { pal_trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); pal_trx_bit_write(SR_OQPSK_SUB1_RC_EN, HALF_SINE_FILTERING); } // Compliant ACK timing pal_trx_bit_write(SR_AACK_ACK_TIME, AACK_ACK_TIME_12_SYMBOLS); tal_pib_SupportedChannels = TRX_SUPPORTED_CHANNELS; pal_trx_bit_write(SR_CC_BAND, 0); pal_trx_bit_write(SR_CHANNEL, tal_pib_CurrentChannel); break; case 5: /* CHINESE_BAND, O-QPSK */ pal_trx_bit_write(SR_BPSK_OQPSK, OQPSK_MODE); pal_trx_bit_write(SR_GC_TX_OFFS, OQPSK_TX_OFFSET); pal_trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_100_KBPS_OR_250_KBPS); pal_trx_bit_write(SR_OQPSK_SUB1_RC_EN, RC_0_8_FILTERING); pal_trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); // Compliant ACK timing pal_trx_bit_write(SR_AACK_ACK_TIME, AACK_ACK_TIME_12_SYMBOLS); tal_pib_SupportedChannels = TRX_SUPPORTED_CHANNELS_CHINA; /* Channel Page 5 supports channels 0-3. */ if (tal_pib_CurrentChannel > 3) { tal_pib_CurrentChannel = 0; } pal_trx_bit_write(SR_CC_BAND, 4); pal_trx_bit_write(SR_CC_NUMBER, GET_CHINA_FREQ(tal_pib_CurrentChannel)); break; #ifdef HIGH_DATA_RATE_SUPPORT case 16: /* non-compliant OQPSK mode 1 */ pal_trx_bit_write(SR_BPSK_OQPSK, OQPSK_MODE); pal_trx_bit_write(SR_GC_TX_OFFS, OQPSK_TX_OFFSET); pal_trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_200_KBPS_OR_500_KBPS); if (tal_pib_CurrentChannel == 0) { pal_trx_bit_write(SR_SUB_MODE, LOW_DATA_RATE); } else { pal_trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); pal_trx_bit_write(SR_OQPSK_SUB1_RC_EN, HALF_SINE_FILTERING); } // Reduced ACK timing pal_trx_bit_write(SR_AACK_ACK_TIME, AACK_ACK_TIME_2_SYMBOLS); tal_pib_SupportedChannels = TRX_SUPPORTED_CHANNELS; pal_trx_bit_write(SR_CC_BAND, 0); pal_trx_bit_write(SR_CHANNEL, tal_pib_CurrentChannel); break; case 17: /* non-compliant OQPSK mode 2 */ pal_trx_bit_write(SR_BPSK_OQPSK, OQPSK_MODE); pal_trx_bit_write(SR_GC_TX_OFFS, OQPSK_TX_OFFSET); pal_trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_400_KBPS_OR_1_MBPS); if (tal_pib_CurrentChannel == 0) { pal_trx_bit_write(SR_SUB_MODE, LOW_DATA_RATE); } else { pal_trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); pal_trx_bit_write(SR_OQPSK_SUB1_RC_EN, HALF_SINE_FILTERING); } // Reduced ACK timing pal_trx_bit_write(SR_AACK_ACK_TIME, AACK_ACK_TIME_2_SYMBOLS); tal_pib_SupportedChannels = TRX_SUPPORTED_CHANNELS; pal_trx_bit_write(SR_CC_BAND, 0); pal_trx_bit_write(SR_CHANNEL, tal_pib_CurrentChannel); break; case 18: /* Chinese band, non-compliant mode 1 using O-QPSK 500 */ pal_trx_bit_write(SR_BPSK_OQPSK, OQPSK_MODE); pal_trx_bit_write(SR_GC_TX_OFFS, OQPSK_TX_OFFSET); pal_trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_200_KBPS_OR_500_KBPS); pal_trx_bit_write(SR_OQPSK_SUB1_RC_EN, RC_0_8_FILTERING); pal_trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); // Reduced ACK timing pal_trx_bit_write(SR_AACK_ACK_TIME, AACK_ACK_TIME_2_SYMBOLS); tal_pib_SupportedChannels = TRX_SUPPORTED_CHANNELS_CHINA; /* Channel Page 18 supports channels 0-3. */ if (tal_pib_CurrentChannel > 3) { tal_pib_CurrentChannel = 0; } pal_trx_bit_write(SR_CC_BAND, 4); pal_trx_bit_write(SR_CC_NUMBER, GET_CHINA_FREQ(tal_pib_CurrentChannel)); break; case 19: /* Chinese band, non-compliant mode 2 using O-QPSK 1000 */ pal_trx_bit_write(SR_BPSK_OQPSK, OQPSK_MODE); pal_trx_bit_write(SR_GC_TX_OFFS, OQPSK_TX_OFFSET); pal_trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_400_KBPS_OR_1_MBPS); pal_trx_bit_write(SR_OQPSK_SUB1_RC_EN, RC_0_8_FILTERING); pal_trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); // Reduced ACK timing pal_trx_bit_write(SR_AACK_ACK_TIME, AACK_ACK_TIME_2_SYMBOLS); tal_pib_SupportedChannels = TRX_SUPPORTED_CHANNELS_CHINA; /* Channel Page 18 supports channels 0-3. */ if (tal_pib_CurrentChannel > 3) { tal_pib_CurrentChannel = 0; } pal_trx_bit_write(SR_CC_BAND, 4); pal_trx_bit_write(SR_CC_NUMBER, GET_CHINA_FREQ(tal_pib_CurrentChannel)); break; #endif /* #ifdef HIGH_DATA_RATE_SUPPORT */ default: return false; } return true; }
/** * \brief Apply channel page configuartion to transceiver * * \param ch_page Channel page * * \return true if changes could be applied else false */ static bool apply_channel_page_configuration(uint8_t ch_page) { /* * Before updating the transceiver a number of TAL PIB attributes need * to be updated depending on the channel page. */ /* \todo these configurations are not rate dependent here! But shall be! **/ tal_pib.MaxFrameDuration = MAX_FRAME_DURATION; tal_pib.SHRDuration = NO_OF_SYMBOLS_PREAMBLE_SFD; tal_pib.SymbolsPerOctet = SYMBOLS_PER_OCTET; switch (ch_page) { case 0: /* BPSK */ trx_bit_write(SR_BPSK_OQPSK, BPSK_MODE); trx_bit_write(SR_GC_TX_OFFS, BPSK_TX_OFFSET); trx_bit_write(SR_ALT_SPECTRUM, ALT_SPECTRUM_DISABLE); if (tal_pib.CurrentChannel == 0) { /* BPSK20, EU */ trx_bit_write(SR_SUB_MODE, LOW_DATA_RATE); } else { /* BPSK40, NA */ trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); } /* Compliant ACK timing */ trx_bit_write(SR_AACK_ACK_TIME, ACK_TIME_12_SYMBOLS); tal_pib.SupportedChannels = TRX_SUPPORTED_CHANNELS; trx_bit_write(SR_CC_BAND, 0); trx_bit_write(SR_CHANNEL, tal_pib.CurrentChannel); break; case 2: /* O-QPSK */ trx_bit_write(SR_BPSK_OQPSK, OQPSK_MODE); trx_bit_write(SR_GC_TX_OFFS, OQPSK_TX_OFFSET); trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_100_KBPS_OR_250_KBPS); trx_bit_write(SR_ALT_SPECTRUM, ALT_SPECTRUM_DISABLE); if (tal_pib.CurrentChannel == 0) { /* OQPSK100, EU */ trx_bit_write(SR_SUB_MODE, LOW_DATA_RATE); } else { /* OQPSK250, NA */ trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); } /* Compliant ACK timing */ trx_bit_write(SR_AACK_ACK_TIME, ACK_TIME_12_SYMBOLS); tal_pib.SupportedChannels = TRX_SUPPORTED_CHANNELS; trx_bit_write(SR_CC_BAND, 0); trx_bit_write(SR_CHANNEL, tal_pib.CurrentChannel); break; case 5: /* CHINESE_BAND, O-QPSK */ trx_bit_write(SR_BPSK_OQPSK, OQPSK_MODE); trx_bit_write(SR_GC_TX_OFFS, OQPSK_TX_OFFSET); trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_100_KBPS_OR_250_KBPS); trx_bit_write(SR_ALT_SPECTRUM, ALT_SPECTRUM_ENABLE); trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); /* Compliant ACK timing */ trx_bit_write(SR_AACK_ACK_TIME, ACK_TIME_12_SYMBOLS); tal_pib.SupportedChannels = TRX_SUPPORTED_CHANNELS_CHINA; /* Channel Page 5 supports channels 0-3. */ if (tal_pib.CurrentChannel > 3) { tal_pib.CurrentChannel = 0; } trx_bit_write(SR_CC_BAND, 4); trx_bit_write(SR_CC_NUMBER, GET_CHINA_FREQ(tal_pib.CurrentChannel)); break; #ifdef HIGH_DATA_RATE_SUPPORT case 16: /* non-compliant OQPSK mode 1 */ trx_bit_write(SR_BPSK_OQPSK, OQPSK_MODE); trx_bit_write(SR_GC_TX_OFFS, OQPSK_TX_OFFSET); trx_bit_write(SR_ALT_SPECTRUM, ALT_SPECTRUM_DISABLE); trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_200_KBPS_OR_500_KBPS); if (tal_pib.CurrentChannel == 0) { /* 200kbps, EU */ trx_bit_write(SR_SUB_MODE, LOW_DATA_RATE); } else { /* 500kbps, NA */ trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); } /* Reduced ACK timing */ trx_bit_write(SR_AACK_ACK_TIME, ACK_TIME_2_SYMBOLS); tal_pib.SupportedChannels = TRX_SUPPORTED_CHANNELS; trx_bit_write(SR_CC_BAND, 0); trx_bit_write(SR_CHANNEL, tal_pib.CurrentChannel); break; case 17: /* non-compliant OQPSK mode 2 */ trx_bit_write(SR_BPSK_OQPSK, OQPSK_MODE); trx_bit_write(SR_GC_TX_OFFS, OQPSK_TX_OFFSET); trx_bit_write(SR_ALT_SPECTRUM, ALT_SPECTRUM_DISABLE); trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_400_KBPS_OR_1_MBPS); if (tal_pib.CurrentChannel == 0) { /* 400kbps, EU */ trx_bit_write(SR_SUB_MODE, LOW_DATA_RATE); } else { /* 1000kbps, NA */ trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); } /* Reduced ACK timing */ trx_bit_write(SR_AACK_ACK_TIME, ACK_TIME_2_SYMBOLS); tal_pib.SupportedChannels = TRX_SUPPORTED_CHANNELS; trx_bit_write(SR_CC_BAND, 0); trx_bit_write(SR_CHANNEL, tal_pib.CurrentChannel); break; case 18: /* Chinese band, non-compliant mode 1 using O-QPSK 500 */ trx_bit_write(SR_BPSK_OQPSK, OQPSK_MODE); trx_bit_write(SR_GC_TX_OFFS, OQPSK_TX_OFFSET); trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_200_KBPS_OR_500_KBPS); trx_bit_write(SR_ALT_SPECTRUM, ALT_SPECTRUM_ENABLE); trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); /* Reduced ACK timing */ trx_bit_write(SR_AACK_ACK_TIME, ACK_TIME_2_SYMBOLS); tal_pib.SupportedChannels = TRX_SUPPORTED_CHANNELS_CHINA; /* Channel Page 18 supports channels 0-3. */ if (tal_pib.CurrentChannel > 3) { tal_pib.CurrentChannel = 0; } trx_bit_write(SR_CC_BAND, 4); trx_bit_write(SR_CC_NUMBER, GET_CHINA_FREQ(tal_pib.CurrentChannel)); break; case 19: /* Chinese band, non-compliant mode 2 using O-QPSK 1000 */ trx_bit_write(SR_BPSK_OQPSK, OQPSK_MODE); trx_bit_write(SR_GC_TX_OFFS, OQPSK_TX_OFFSET); trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_400_KBPS_OR_1_MBPS); trx_bit_write(SR_ALT_SPECTRUM, ALT_SPECTRUM_ENABLE); trx_bit_write(SR_SUB_MODE, HIGH_DATA_RATE); /* Reduced ACK timing */ trx_bit_write(SR_AACK_ACK_TIME, ACK_TIME_2_SYMBOLS); tal_pib.SupportedChannels = TRX_SUPPORTED_CHANNELS_CHINA; /* Channel Page 18 supports channels 0-3. */ if (tal_pib.CurrentChannel > 3) { tal_pib.CurrentChannel = 0; } trx_bit_write(SR_CC_BAND, 4); trx_bit_write(SR_CC_NUMBER, GET_CHINA_FREQ(tal_pib.CurrentChannel)); break; #endif /* #ifdef HIGH_DATA_RATE_SUPPORT */ default: return false; } return true; }