pamoja.radios.sx127x

The Semtech SX1276, SX1277, SX1278, and SX1279, as the register values they take.

These radios, and modules built on them such as the RFM95W, are driven through registers. Each SPI transaction starts with an address byte whose top bit is set for a write, followed by the data, and the address advances with each byte except at the FIFO. These functions give the addresses, the values a LoRa link and an output power put in them, and the readings decoded, from the SX1276/77/78/79 datasheet (Rev 7), so a program with its own SPI access can drive the chip.

  1"""The Semtech SX1276, SX1277, SX1278, and SX1279, as the register values they take.
  2
  3These radios, and modules built on them such as the RFM95W, are driven through registers.
  4Each SPI transaction starts with an address byte whose top bit is set for a write, followed
  5by the data, and the address advances with each byte except at the FIFO. These functions
  6give the addresses, the values a LoRa link and an output power put in them, and the
  7readings decoded, from the SX1276/77/78/79 datasheet (Rev 7), so a program with its own SPI
  8access can drive the chip.
  9"""
 10
 11from __future__ import annotations
 12
 13from enum import Enum, IntEnum, IntFlag
 14
 15from pamoja._native import (
 16    LinkBudget,
 17    LoraLink,
 18    Sx127xHighBwOptimize as HighBwOptimize,
 19    Sx127xModem as Modem,
 20    Sx127xModemStatus as ModemStatus,
 21    Sx127xPacketStatus as PacketStatus,
 22    Sx127xSpuriousReception as SpuriousReception,
 23    Sx127xTxPower as TxPower,
 24)
 25from pamoja._native import sx127x_automatic_if as _automatic_if
 26from pamoja._native import sx127x_constants as _constants
 27from pamoja._native import sx127x_frequency_from_word as _frequency_from_word
 28from pamoja._native import sx127x_frequency_word as _frequency_word
 29from pamoja._native import sx127x_fsk_op_mode as _fsk_op_mode
 30from pamoja._native import sx127x_high_bw_optimize as _high_bw_optimize
 31from pamoja._native import sx127x_image_cal_start as _image_cal_start
 32from pamoja._native import sx127x_invert_iq as _invert_iq
 33from pamoja._native import sx127x_invert_iq_2 as _invert_iq_2
 34from pamoja._native import sx127x_irq_flags as _irq_flags
 35from pamoja._native import sx127x_lora_op_mode as _lora_op_mode
 36from pamoja._native import sx127x_mode_from_op_mode as _mode_from_op_mode
 37from pamoja._native import sx127x_modem as _modem
 38from pamoja._native import sx127x_modem_status as _modem_status
 39from pamoja._native import sx127x_ocp_register as _ocp_register
 40from pamoja._native import sx127x_packet_status as _packet_status
 41from pamoja._native import sx127x_read_address as _read_address
 42from pamoja._native import sx127x_registers as _registers
 43from pamoja._native import sx127x_rssi_dbm as _rssi_dbm
 44from pamoja._native import sx127x_spurious_reception as _spurious_reception
 45from pamoja._native import sx127x_symbol_timeout as _symbol_timeout
 46from pamoja._native import sx127x_tx_power as _tx_power
 47from pamoja._native import sx127x_tx_power_under_ceiling as _tx_power_under_ceiling
 48from pamoja._native import sx127x_write_address as _write_address
 49
 50__all__ = [
 51    "IMAGE_CAL_RUNNING",
 52    "IMAGE_CAL_START",
 53    "LNA_BOOSTED",
 54    "PA_DAC_DEFAULT",
 55    "PA_DAC_HIGH_POWER",
 56    "SYNC_WORD_PRIVATE",
 57    "SYNC_WORD_PUBLIC",
 58    "TCXO_INPUT_ON",
 59    "VERSION",
 60    "WRITE",
 61    "Dio0",
 62    "HighBwOptimize",
 63    "Irq",
 64    "Mode",
 65    "Modem",
 66    "ModemStatus",
 67    "PaOutput",
 68    "PacketStatus",
 69    "Register",
 70    "SpuriousReception",
 71    "TxPower",
 72    "automatic_if",
 73    "frequency_from_word",
 74    "frequency_word",
 75    "fsk_op_mode",
 76    "high_bw_optimize",
 77    "image_cal_start",
 78    "invert_iq",
 79    "invert_iq_2",
 80    "lora_op_mode",
 81    "mode_from_op_mode",
 82    "modem",
 83    "modem_status",
 84    "ocp_register",
 85    "packet_status",
 86    "read_address",
 87    "rssi_dbm",
 88    "spurious_reception",
 89    "symbol_timeout",
 90    "tx_power",
 91    "tx_power_under_ceiling",
 92    "write_address",
 93]
 94
 95_REGISTERS = _registers()
 96_CONSTANTS = _constants()
 97_IRQ_FLAGS = _irq_flags()
 98
 99#: The RegVersion value of an SX1276, SX1277, SX1278, or SX1279.
100VERSION = _CONSTANTS["version"]
101#: The bit of an address byte that makes an access a write.
102WRITE = _CONSTANTS["write"]
103#: The sync word the datasheet reserves for LoRaWAN networks.
104SYNC_WORD_PUBLIC = _CONSTANTS["syncWordPublic"]
105#: The private sync word, and the chip's reset value.
106SYNC_WORD_PRIVATE = _CONSTANTS["syncWordPrivate"]
107#: RegPaDac at its reset value.
108PA_DAC_DEFAULT = _CONSTANTS["paDacDefault"]
109#: RegPaDac with the +20 dBm setting on PA_BOOST.
110PA_DAC_HIGH_POWER = _CONSTANTS["paDacHighPower"]
111#: The RegImageCal bit that starts a calibration.
112IMAGE_CAL_START = _CONSTANTS["imageCalStart"]
113#: The RegImageCal bit set while a calibration runs.
114IMAGE_CAL_RUNNING = _CONSTANTS["imageCalRunning"]
115#: RegLna with maximum gain and the high frequency LNA boost.
116LNA_BOOSTED = _CONSTANTS["lnaBoosted"]
117#: RegTcxo for a module clocked by a TCXO.
118TCXO_INPUT_ON = _CONSTANTS["tcxoInputOn"]
119
120
121class Register(IntEnum):
122    """The register addresses, from Table 41 of the datasheet with the LoRa page selected."""
123
124    #: RegFifo, the LoRa data buffer, read or written at RegFifoAddrPtr.
125    FIFO = _REGISTERS["fifo"]
126    #: RegOpMode: LoRa or FSK, the register page, and the operating mode.
127    OP_MODE = _REGISTERS["opMode"]
128    #: RegFrfMsb, the top byte of the carrier word.
129    FRF_MSB = _REGISTERS["frfMsb"]
130    #: RegFrfMid, the middle byte of the carrier word.
131    FRF_MID = _REGISTERS["frfMid"]
132    #: RegFrfLsb, the low byte of the carrier word.
133    FRF_LSB = _REGISTERS["frfLsb"]
134    #: RegPaConfig: the amplifier output, its maximum, and the power.
135    PA_CONFIG = _REGISTERS["paConfig"]
136    #: RegPaRamp, the amplifier ramp time.
137    PA_RAMP = _REGISTERS["paRamp"]
138    #: RegOcp, the amplifier current limit.
139    OCP = _REGISTERS["ocp"]
140    #: RegLna, the LNA gain and current.
141    LNA = _REGISTERS["lna"]
142    #: RegFifoAddrPtr, where the next RegFifo access lands.
143    FIFO_ADDR_PTR = _REGISTERS["fifoAddrPtr"]
144    #: RegFifoTxBaseAddr, where a transmitted payload starts.
145    FIFO_TX_BASE_ADDR = _REGISTERS["fifoTxBaseAddr"]
146    #: RegFifoRxBaseAddr, where received payloads start.
147    FIFO_RX_BASE_ADDR = _REGISTERS["fifoRxBaseAddr"]
148    #: RegFifoRxCurrentAddr, where the last received packet starts.
149    FIFO_RX_CURRENT_ADDR = _REGISTERS["fifoRxCurrentAddr"]
150    #: RegIrqFlagsMask, the interrupts masked off.
151    IRQ_FLAGS_MASK = _REGISTERS["irqFlagsMask"]
152    #: RegIrqFlags, the interrupts raised, each cleared by writing it back as a 1.
153    IRQ_FLAGS = _REGISTERS["irqFlags"]
154    #: RegRxNbBytes, the payload length of the last packet received.
155    RX_NB_BYTES = _REGISTERS["rxNbBytes"]
156    #: RegModemStat, the live state of the modem.
157    MODEM_STAT = _REGISTERS["modemStat"]
158    #: RegPktSnrValue, the SNR of the last packet in quarters of a decibel.
159    PKT_SNR_VALUE = _REGISTERS["pktSnrValue"]
160    #: RegPktRssiValue, the RSSI of the last packet.
161    PKT_RSSI_VALUE = _REGISTERS["pktRssiValue"]
162    #: RegRssiValue, the RSSI the receiver hears right now.
163    RSSI_VALUE = _REGISTERS["rssiValue"]
164    #: RegHopChannel, the PLL lock and the CRC the last header announced.
165    HOP_CHANNEL = _REGISTERS["hopChannel"]
166    #: RegModemConfig1: bandwidth, coding rate, and header mode.
167    MODEM_CONFIG_1 = _REGISTERS["modemConfig1"]
168    #: RegModemConfig2: spreading factor, CRC, and the top bits of the symbol timeout.
169    MODEM_CONFIG_2 = _REGISTERS["modemConfig2"]
170    #: RegSymbTimeoutLsb, the low byte of the symbol timeout.
171    SYMB_TIMEOUT_LSB = _REGISTERS["symbTimeoutLsb"]
172    #: RegPreambleMsb, the high byte of the preamble length.
173    PREAMBLE_MSB = _REGISTERS["preambleMsb"]
174    #: RegPreambleLsb, the low byte of the preamble length.
175    PREAMBLE_LSB = _REGISTERS["preambleLsb"]
176    #: RegPayloadLength, the payload length to send.
177    PAYLOAD_LENGTH = _REGISTERS["payloadLength"]
178    #: RegMaxPayloadLength, the longest payload a received header may announce.
179    MAX_PAYLOAD_LENGTH = _REGISTERS["maxPayloadLength"]
180    #: RegModemConfig3: low data rate optimization and the automatic gain control.
181    MODEM_CONFIG_3 = _REGISTERS["modemConfig3"]
182    #: RegRssiWideband, a wideband RSSI sample.
183    RSSI_WIDEBAND = _REGISTERS["rssiWideband"]
184    #: RegIfFreq2, which the spurious reception erratum sets.
185    IF_FREQ_2 = _REGISTERS["ifFreq2"]
186    #: RegIfFreq1, which the spurious reception erratum clears.
187    IF_FREQ_1 = _REGISTERS["ifFreq1"]
188    #: RegDetectOptimize: the automatic IF and the detection optimization.
189    DETECT_OPTIMIZE = _REGISTERS["detectOptimize"]
190    #: RegInvertIQ, the IQ polarity of each path.
191    INVERT_IQ = _REGISTERS["invertIq"]
192    #: RegHighBwOptimize1, which the 500 kHz erratum sets.
193    HIGH_BW_OPTIMIZE_1 = _REGISTERS["highBwOptimize1"]
194    #: RegDetectionThreshold, the LoRa detection threshold.
195    DETECTION_THRESHOLD = _REGISTERS["detectionThreshold"]
196    #: RegSyncWord, the LoRa sync word.
197    SYNC_WORD = _REGISTERS["syncWord"]
198    #: RegHighBwOptimize2, which the 500 kHz erratum sets.
199    HIGH_BW_OPTIMIZE_2 = _REGISTERS["highBwOptimize2"]
200    #: RegInvertIQ2, which completes an IQ inversion.
201    INVERT_IQ_2 = _REGISTERS["invertIq2"]
202    #: RegImageCal, at the address of RegInvertIQ2 on the FSK page.
203    IMAGE_CAL = _REGISTERS["imageCal"]
204    #: RegDioMapping1, the events DIO0 to DIO3 signal.
205    DIO_MAPPING_1 = _REGISTERS["dioMapping1"]
206    #: RegDioMapping2, the events DIO4 and DIO5 signal.
207    DIO_MAPPING_2 = _REGISTERS["dioMapping2"]
208    #: RegVersion, the silicon revision.
209    VERSION = _REGISTERS["version"]
210    #: RegTcxo, a crystal or a TCXO on XTA.
211    TCXO = _REGISTERS["tcxo"]
212    #: RegPaDac, the +20 dBm setting of PA_BOOST.
213    PA_DAC = _REGISTERS["paDac"]
214
215
216class Dio0(IntEnum):
217    """The RegDioMapping1 values that route an event to DIO0, from Table 18 of the datasheet."""
218
219    #: DIO0 signals RxDone.
220    RX_DONE = _CONSTANTS["dio0RxDone"]
221    #: DIO0 signals TxDone.
222    TX_DONE = _CONSTANTS["dio0TxDone"]
223    #: DIO0 signals CadDone.
224    CAD_DONE = _CONSTANTS["dio0CadDone"]
225
226
227class Irq(IntFlag):
228    """The LoRa interrupt flags of RegIrqFlags."""
229
230    #: A single reception timed out before a preamble arrived.
231    RX_TIMEOUT = _IRQ_FLAGS["rxTimeout"]
232    #: A packet has been received.
233    RX_DONE = _IRQ_FLAGS["rxDone"]
234    #: The payload failed its CRC.
235    PAYLOAD_CRC_ERROR = _IRQ_FLAGS["payloadCrcError"]
236    #: A valid header was received.
237    VALID_HEADER = _IRQ_FLAGS["validHeader"]
238    #: The payload has been transmitted.
239    TX_DONE = _IRQ_FLAGS["txDone"]
240    #: Channel activity detection finished.
241    CAD_DONE = _IRQ_FLAGS["cadDone"]
242    #: Frequency hopping moved to the next channel.
243    FHSS_CHANGE_CHANNEL = _IRQ_FLAGS["fhssChangeChannel"]
244    #: Channel activity detection heard a LoRa signal.
245    CAD_DETECTED = _IRQ_FLAGS["cadDetected"]
246
247
248class PaOutput(str, Enum):
249    """The amplifier output a module wires to its antenna.
250
251    The SPI interface cannot see which output a module uses, so the caller names it.
252    """
253
254    #: The high efficiency amplifier on RFO_LF or RFO_HF, -4 to +15 dBm.
255    RFO = "Rfo"
256    #: The regulated amplifier on PA_BOOST, +2 to +20 dBm, as on the RFM95W.
257    PA_BOOST = "PaBoost"
258
259
260class Mode(str, Enum):
261    """The operating modes of RegOpMode."""
262
263    #: Only the SPI interface and the registers are powered; the only mode that may switch modems.
264    SLEEP = "Sleep"
265    #: The oscillator and the baseband are on.
266    STANDBY = "Standby"
267    #: The PLL is locked for transmit.
268    FS_TX = "FsTx"
269    #: One packet goes out, then the chip returns to standby.
270    TX = "Tx"
271    #: The PLL is locked for receive.
272    FS_RX = "FsRx"
273    #: The receiver takes packet after packet.
274    RX_CONTINUOUS = "RxContinuous"
275    #: The receiver waits for one packet or the symbol timeout.
276    RX_SINGLE = "RxSingle"
277    #: Channel activity detection looks for a LoRa preamble.
278    CAD = "Cad"
279
280
281def frequency_word(frequency_hz: int) -> int:
282    """Return the 24-bit RegFrf word for a frequency.
283
284    :param frequency_hz: The carrier frequency in hertz.
285    :returns: The frequency times 2^19 over the 32 MHz crystal, rounded to the nearest step.
286
287    >>> hex(frequency_word(868_100_000))
288    '0xd90666'
289    """
290    return _frequency_word(frequency_hz)
291
292
293def frequency_from_word(word: int) -> int:
294    """Return the frequency a RegFrf word selects.
295
296    :param word: The 24-bit frequency word.
297    :returns: The carrier frequency in hertz.
298    """
299    return _frequency_from_word(word)
300
301
302def read_address(address: int) -> int:
303    """Return the address byte that reads a register.
304
305    :param address: The register address.
306    :returns: The address with the write bit clear.
307    """
308    return _read_address(address)
309
310
311def write_address(address: int) -> int:
312    """Return the address byte that writes a register.
313
314    :param address: The register address.
315    :returns: The address with the write bit set.
316    """
317    return _write_address(address)
318
319
320def lora_op_mode(mode: Mode | str) -> int:
321    """Return the RegOpMode value for a LoRa operating mode.
322
323    :param mode: The operating mode.
324    :returns: The register value, with the LoRa register page selected.
325    :raises ValueError: If no mode goes by that name.
326    """
327    return _lora_op_mode(Mode(mode).value)
328
329
330def fsk_op_mode(mode: Mode | str) -> int:
331    """Return the RegOpMode value for an FSK operating mode, which image calibration needs.
332
333    :param mode: The operating mode.
334    :returns: The register value.
335    :raises ValueError: If no mode goes by that name.
336    """
337    return _fsk_op_mode(Mode(mode).value)
338
339
340def mode_from_op_mode(op_mode: int) -> Mode:
341    """Return the operating mode a RegOpMode value holds.
342
343    :param op_mode: The register value.
344    :returns: The mode.
345    """
346    return Mode(_mode_from_op_mode(op_mode))
347
348
349def modem(link: LoraLink, frequency_hz: int, symbol_timeout: int = 0) -> Modem:
350    """Return the LoRa modem registers for a link at a carrier.
351
352    :param link: The link settings.
353    :param frequency_hz: The carrier frequency, which rules out 250 and 500 kHz below 175 MHz.
354    :param symbol_timeout: A single reception timeout in symbols, whose top bits go in
355        RegModemConfig2.
356    :returns: RegModemConfig1 to 3 and the SF6 detection settings.
357    :raises PamojaError: If the SX127x cannot use the link at the carrier.
358    """
359    return _modem(link, frequency_hz, symbol_timeout)
360
361
362def symbol_timeout(link: LoraLink, timeout_us: int) -> int:
363    """Return a single reception timeout in the link's symbols.
364
365    :param link: The link settings, whose symbol time counts the timeout.
366    :param timeout_us: How long to listen for a preamble, in microseconds.
367    :returns: The timeout rounded up to whole symbols, from 4 to 1023.
368    """
369    return _symbol_timeout(link, timeout_us)
370
371
372def tx_power(output: PaOutput | str, output_dbm: int) -> TxPower:
373    """Choose the amplifier settings for an output power.
374
375    :param output: The amplifier output the module uses.
376    :param output_dbm: The output power wanted, in dBm.
377    :returns: The settings, clamped to what the output delivers.
378    :raises ValueError: If no output goes by that name.
379    """
380    return _tx_power(PaOutput(output).value, output_dbm)
381
382
383def tx_power_under_ceiling(
384    output: PaOutput | str, budget: LinkBudget, eirp_ceiling_dbm: float
385) -> TxPower:
386    """Choose the amplifier settings that keep a link's EIRP at or under a ceiling.
387
388    :param output: The amplifier output the module uses.
389    :param budget: The link budget, whose transmitting antenna and cable apply.
390    :param eirp_ceiling_dbm: The EIRP limit in dBm.
391    :returns: The settings, rounded down to whole decibels.
392    :raises ValueError: If no output goes by that name.
393    """
394    return _tx_power_under_ceiling(PaOutput(output).value, budget, eirp_ceiling_dbm)
395
396
397def ocp_register(milliamps: int) -> int:
398    """Return RegOcp for a current limit.
399
400    :param milliamps: The most current the amplifier may draw.
401    :returns: The register value with the protection on.
402    """
403    return _ocp_register(milliamps)
404
405
406def invert_iq(receive: bool, transmit: bool) -> int:
407    """Return RegInvertIQ for the IQ polarity of each path.
408
409    :param receive: Whether to invert the receive path, as a LoRaWAN device does for downlinks.
410    :param transmit: Whether to invert the transmit path, as a gateway does.
411    :returns: The register value, with the transmit bit set for normal IQ as the reference
412        drivers have it.
413    """
414    return _invert_iq(receive, transmit)
415
416
417def invert_iq_2(inverted: bool) -> int:
418    """Return RegInvertIQ2 for the path in use.
419
420    :param inverted: Whether that path is inverted.
421    :returns: 0x19 when inverted, else 0x1D.
422    """
423    return _invert_iq_2(inverted)
424
425
426def high_bw_optimize(link: LoraLink, frequency_hz: int) -> HighBwOptimize:
427    """Return the writes of the 500 kHz sensitivity erratum.
428
429    :param link: The link settings, whose bandwidth decides.
430    :param frequency_hz: The carrier frequency in hertz.
431    :returns: RegHighBwOptimize1 and, where it is written, RegHighBwOptimize2.
432    :raises PamojaError: If the SX127x has no such bandwidth.
433    """
434    return _high_bw_optimize(link, frequency_hz)
435
436
437def spurious_reception(link: LoraLink) -> SpuriousReception:
438    """Return the receive settings of the spurious reception erratum.
439
440    :param link: The link settings, whose bandwidth decides.
441    :returns: The automatic IF, the hand-set IF, and the carrier offset.
442    :raises PamojaError: If the SX127x has no such bandwidth.
443    """
444    return _spurious_reception(link)
445
446
447def image_cal_start(current: int) -> int:
448    """Return RegImageCal to start a calibration.
449
450    :param current: The register's current value.
451    :returns: The value with ImageCalStart set and AutoImageCalOn clear.
452    """
453    return _image_cal_start(current)
454
455
456def automatic_if(current: int, on: bool) -> int:
457    """Return RegDetectOptimize with AutomaticIFOn set or clear.
458
459    :param current: The register's current value.
460    :param on: Whether the automatic IF stays on.
461    :returns: The register value.
462    """
463    return _automatic_if(current, on)
464
465
466def packet_status(answer: bytes, frequency_hz: int) -> PacketStatus:
467    """Decode RegPktSnrValue and RegPktRssiValue, read together.
468
469    :param answer: The two register values, SNR first.
470    :param frequency_hz: The carrier the packet was heard at, which picks the RF port's offset.
471    :returns: The three signal levels, exact to a hundredth of a decibel.
472    :raises ValueError: If the answer is not two bytes.
473    """
474    return _packet_status(bytes(answer), frequency_hz)
475
476
477def rssi_dbm(byte: int, frequency_hz: int) -> float:
478    """Decode RegRssiValue.
479
480    :param byte: The register value.
481    :param frequency_hz: The carrier the receiver is tuned to.
482    :returns: The signal power the receiver hears right now, in dBm.
483    """
484    return _rssi_dbm(byte, frequency_hz)
485
486
487def modem_status(byte: int) -> ModemStatus:
488    """Decode RegModemStat.
489
490    :param byte: The register value.
491    :returns: The modem's live state.
492    """
493    return _modem_status(byte)
IMAGE_CAL_RUNNING = 32
IMAGE_CAL_START = 64
LNA_BOOSTED = 35
PA_DAC_DEFAULT = 132
PA_DAC_HIGH_POWER = 135
SYNC_WORD_PRIVATE = 18
SYNC_WORD_PUBLIC = 52
TCXO_INPUT_ON = 25
VERSION = 18
WRITE = 128
class Dio0(enum.IntEnum):
217class Dio0(IntEnum):
218    """The RegDioMapping1 values that route an event to DIO0, from Table 18 of the datasheet."""
219
220    #: DIO0 signals RxDone.
221    RX_DONE = _CONSTANTS["dio0RxDone"]
222    #: DIO0 signals TxDone.
223    TX_DONE = _CONSTANTS["dio0TxDone"]
224    #: DIO0 signals CadDone.
225    CAD_DONE = _CONSTANTS["dio0CadDone"]

The RegDioMapping1 values that route an event to DIO0, from Table 18 of the datasheet.

RX_DONE = <Dio0.RX_DONE: 0>
TX_DONE = <Dio0.TX_DONE: 64>
CAD_DONE = <Dio0.CAD_DONE: 128>
HighBwOptimize = <class 'builtins.Sx127xHighBwOptimize'>
class Irq(enum.IntFlag):
228class Irq(IntFlag):
229    """The LoRa interrupt flags of RegIrqFlags."""
230
231    #: A single reception timed out before a preamble arrived.
232    RX_TIMEOUT = _IRQ_FLAGS["rxTimeout"]
233    #: A packet has been received.
234    RX_DONE = _IRQ_FLAGS["rxDone"]
235    #: The payload failed its CRC.
236    PAYLOAD_CRC_ERROR = _IRQ_FLAGS["payloadCrcError"]
237    #: A valid header was received.
238    VALID_HEADER = _IRQ_FLAGS["validHeader"]
239    #: The payload has been transmitted.
240    TX_DONE = _IRQ_FLAGS["txDone"]
241    #: Channel activity detection finished.
242    CAD_DONE = _IRQ_FLAGS["cadDone"]
243    #: Frequency hopping moved to the next channel.
244    FHSS_CHANGE_CHANNEL = _IRQ_FLAGS["fhssChangeChannel"]
245    #: Channel activity detection heard a LoRa signal.
246    CAD_DETECTED = _IRQ_FLAGS["cadDetected"]

The LoRa interrupt flags of RegIrqFlags.

RX_TIMEOUT = <Irq.RX_TIMEOUT: 128>
RX_DONE = <Irq.RX_DONE: 64>
PAYLOAD_CRC_ERROR = <Irq.PAYLOAD_CRC_ERROR: 32>
VALID_HEADER = <Irq.VALID_HEADER: 16>
TX_DONE = <Irq.TX_DONE: 8>
CAD_DONE = <Irq.CAD_DONE: 4>
FHSS_CHANGE_CHANNEL = <Irq.FHSS_CHANGE_CHANNEL: 2>
CAD_DETECTED = <Irq.CAD_DETECTED: 1>
class Mode(builtins.str, enum.Enum):
261class Mode(str, Enum):
262    """The operating modes of RegOpMode."""
263
264    #: Only the SPI interface and the registers are powered; the only mode that may switch modems.
265    SLEEP = "Sleep"
266    #: The oscillator and the baseband are on.
267    STANDBY = "Standby"
268    #: The PLL is locked for transmit.
269    FS_TX = "FsTx"
270    #: One packet goes out, then the chip returns to standby.
271    TX = "Tx"
272    #: The PLL is locked for receive.
273    FS_RX = "FsRx"
274    #: The receiver takes packet after packet.
275    RX_CONTINUOUS = "RxContinuous"
276    #: The receiver waits for one packet or the symbol timeout.
277    RX_SINGLE = "RxSingle"
278    #: Channel activity detection looks for a LoRa preamble.
279    CAD = "Cad"

The operating modes of RegOpMode.

SLEEP = <Mode.SLEEP: 'Sleep'>
STANDBY = <Mode.STANDBY: 'Standby'>
FS_TX = <Mode.FS_TX: 'FsTx'>
TX = <Mode.TX: 'Tx'>
FS_RX = <Mode.FS_RX: 'FsRx'>
RX_CONTINUOUS = <Mode.RX_CONTINUOUS: 'RxContinuous'>
RX_SINGLE = <Mode.RX_SINGLE: 'RxSingle'>
CAD = <Mode.CAD: 'Cad'>
Modem = <class 'builtins.Sx127xModem'>
ModemStatus = <class 'builtins.Sx127xModemStatus'>
class PaOutput(builtins.str, enum.Enum):
249class PaOutput(str, Enum):
250    """The amplifier output a module wires to its antenna.
251
252    The SPI interface cannot see which output a module uses, so the caller names it.
253    """
254
255    #: The high efficiency amplifier on RFO_LF or RFO_HF, -4 to +15 dBm.
256    RFO = "Rfo"
257    #: The regulated amplifier on PA_BOOST, +2 to +20 dBm, as on the RFM95W.
258    PA_BOOST = "PaBoost"

The amplifier output a module wires to its antenna.

The SPI interface cannot see which output a module uses, so the caller names it.

RFO = <PaOutput.RFO: 'Rfo'>
PA_BOOST = <PaOutput.PA_BOOST: 'PaBoost'>
PacketStatus = <class 'builtins.Sx127xPacketStatus'>
class Register(enum.IntEnum):
122class Register(IntEnum):
123    """The register addresses, from Table 41 of the datasheet with the LoRa page selected."""
124
125    #: RegFifo, the LoRa data buffer, read or written at RegFifoAddrPtr.
126    FIFO = _REGISTERS["fifo"]
127    #: RegOpMode: LoRa or FSK, the register page, and the operating mode.
128    OP_MODE = _REGISTERS["opMode"]
129    #: RegFrfMsb, the top byte of the carrier word.
130    FRF_MSB = _REGISTERS["frfMsb"]
131    #: RegFrfMid, the middle byte of the carrier word.
132    FRF_MID = _REGISTERS["frfMid"]
133    #: RegFrfLsb, the low byte of the carrier word.
134    FRF_LSB = _REGISTERS["frfLsb"]
135    #: RegPaConfig: the amplifier output, its maximum, and the power.
136    PA_CONFIG = _REGISTERS["paConfig"]
137    #: RegPaRamp, the amplifier ramp time.
138    PA_RAMP = _REGISTERS["paRamp"]
139    #: RegOcp, the amplifier current limit.
140    OCP = _REGISTERS["ocp"]
141    #: RegLna, the LNA gain and current.
142    LNA = _REGISTERS["lna"]
143    #: RegFifoAddrPtr, where the next RegFifo access lands.
144    FIFO_ADDR_PTR = _REGISTERS["fifoAddrPtr"]
145    #: RegFifoTxBaseAddr, where a transmitted payload starts.
146    FIFO_TX_BASE_ADDR = _REGISTERS["fifoTxBaseAddr"]
147    #: RegFifoRxBaseAddr, where received payloads start.
148    FIFO_RX_BASE_ADDR = _REGISTERS["fifoRxBaseAddr"]
149    #: RegFifoRxCurrentAddr, where the last received packet starts.
150    FIFO_RX_CURRENT_ADDR = _REGISTERS["fifoRxCurrentAddr"]
151    #: RegIrqFlagsMask, the interrupts masked off.
152    IRQ_FLAGS_MASK = _REGISTERS["irqFlagsMask"]
153    #: RegIrqFlags, the interrupts raised, each cleared by writing it back as a 1.
154    IRQ_FLAGS = _REGISTERS["irqFlags"]
155    #: RegRxNbBytes, the payload length of the last packet received.
156    RX_NB_BYTES = _REGISTERS["rxNbBytes"]
157    #: RegModemStat, the live state of the modem.
158    MODEM_STAT = _REGISTERS["modemStat"]
159    #: RegPktSnrValue, the SNR of the last packet in quarters of a decibel.
160    PKT_SNR_VALUE = _REGISTERS["pktSnrValue"]
161    #: RegPktRssiValue, the RSSI of the last packet.
162    PKT_RSSI_VALUE = _REGISTERS["pktRssiValue"]
163    #: RegRssiValue, the RSSI the receiver hears right now.
164    RSSI_VALUE = _REGISTERS["rssiValue"]
165    #: RegHopChannel, the PLL lock and the CRC the last header announced.
166    HOP_CHANNEL = _REGISTERS["hopChannel"]
167    #: RegModemConfig1: bandwidth, coding rate, and header mode.
168    MODEM_CONFIG_1 = _REGISTERS["modemConfig1"]
169    #: RegModemConfig2: spreading factor, CRC, and the top bits of the symbol timeout.
170    MODEM_CONFIG_2 = _REGISTERS["modemConfig2"]
171    #: RegSymbTimeoutLsb, the low byte of the symbol timeout.
172    SYMB_TIMEOUT_LSB = _REGISTERS["symbTimeoutLsb"]
173    #: RegPreambleMsb, the high byte of the preamble length.
174    PREAMBLE_MSB = _REGISTERS["preambleMsb"]
175    #: RegPreambleLsb, the low byte of the preamble length.
176    PREAMBLE_LSB = _REGISTERS["preambleLsb"]
177    #: RegPayloadLength, the payload length to send.
178    PAYLOAD_LENGTH = _REGISTERS["payloadLength"]
179    #: RegMaxPayloadLength, the longest payload a received header may announce.
180    MAX_PAYLOAD_LENGTH = _REGISTERS["maxPayloadLength"]
181    #: RegModemConfig3: low data rate optimization and the automatic gain control.
182    MODEM_CONFIG_3 = _REGISTERS["modemConfig3"]
183    #: RegRssiWideband, a wideband RSSI sample.
184    RSSI_WIDEBAND = _REGISTERS["rssiWideband"]
185    #: RegIfFreq2, which the spurious reception erratum sets.
186    IF_FREQ_2 = _REGISTERS["ifFreq2"]
187    #: RegIfFreq1, which the spurious reception erratum clears.
188    IF_FREQ_1 = _REGISTERS["ifFreq1"]
189    #: RegDetectOptimize: the automatic IF and the detection optimization.
190    DETECT_OPTIMIZE = _REGISTERS["detectOptimize"]
191    #: RegInvertIQ, the IQ polarity of each path.
192    INVERT_IQ = _REGISTERS["invertIq"]
193    #: RegHighBwOptimize1, which the 500 kHz erratum sets.
194    HIGH_BW_OPTIMIZE_1 = _REGISTERS["highBwOptimize1"]
195    #: RegDetectionThreshold, the LoRa detection threshold.
196    DETECTION_THRESHOLD = _REGISTERS["detectionThreshold"]
197    #: RegSyncWord, the LoRa sync word.
198    SYNC_WORD = _REGISTERS["syncWord"]
199    #: RegHighBwOptimize2, which the 500 kHz erratum sets.
200    HIGH_BW_OPTIMIZE_2 = _REGISTERS["highBwOptimize2"]
201    #: RegInvertIQ2, which completes an IQ inversion.
202    INVERT_IQ_2 = _REGISTERS["invertIq2"]
203    #: RegImageCal, at the address of RegInvertIQ2 on the FSK page.
204    IMAGE_CAL = _REGISTERS["imageCal"]
205    #: RegDioMapping1, the events DIO0 to DIO3 signal.
206    DIO_MAPPING_1 = _REGISTERS["dioMapping1"]
207    #: RegDioMapping2, the events DIO4 and DIO5 signal.
208    DIO_MAPPING_2 = _REGISTERS["dioMapping2"]
209    #: RegVersion, the silicon revision.
210    VERSION = _REGISTERS["version"]
211    #: RegTcxo, a crystal or a TCXO on XTA.
212    TCXO = _REGISTERS["tcxo"]
213    #: RegPaDac, the +20 dBm setting of PA_BOOST.
214    PA_DAC = _REGISTERS["paDac"]

The register addresses, from Table 41 of the datasheet with the LoRa page selected.

FIFO = <Register.FIFO: 0>
OP_MODE = <Register.OP_MODE: 1>
FRF_MSB = <Register.FRF_MSB: 6>
FRF_MID = <Register.FRF_MID: 7>
FRF_LSB = <Register.FRF_LSB: 8>
PA_CONFIG = <Register.PA_CONFIG: 9>
PA_RAMP = <Register.PA_RAMP: 10>
OCP = <Register.OCP: 11>
LNA = <Register.LNA: 12>
FIFO_ADDR_PTR = <Register.FIFO_ADDR_PTR: 13>
FIFO_TX_BASE_ADDR = <Register.FIFO_TX_BASE_ADDR: 14>
FIFO_RX_BASE_ADDR = <Register.FIFO_RX_BASE_ADDR: 15>
FIFO_RX_CURRENT_ADDR = <Register.FIFO_RX_CURRENT_ADDR: 16>
IRQ_FLAGS_MASK = <Register.IRQ_FLAGS_MASK: 17>
IRQ_FLAGS = <Register.IRQ_FLAGS: 18>
RX_NB_BYTES = <Register.RX_NB_BYTES: 19>
MODEM_STAT = <Register.MODEM_STAT: 24>
PKT_SNR_VALUE = <Register.PKT_SNR_VALUE: 25>
PKT_RSSI_VALUE = <Register.PKT_RSSI_VALUE: 26>
RSSI_VALUE = <Register.RSSI_VALUE: 27>
HOP_CHANNEL = <Register.HOP_CHANNEL: 28>
MODEM_CONFIG_1 = <Register.MODEM_CONFIG_1: 29>
MODEM_CONFIG_2 = <Register.MODEM_CONFIG_2: 30>
SYMB_TIMEOUT_LSB = <Register.SYMB_TIMEOUT_LSB: 31>
PREAMBLE_MSB = <Register.PREAMBLE_MSB: 32>
PREAMBLE_LSB = <Register.PREAMBLE_LSB: 33>
PAYLOAD_LENGTH = <Register.PAYLOAD_LENGTH: 34>
MAX_PAYLOAD_LENGTH = <Register.MAX_PAYLOAD_LENGTH: 35>
MODEM_CONFIG_3 = <Register.MODEM_CONFIG_3: 38>
RSSI_WIDEBAND = <Register.RSSI_WIDEBAND: 44>
IF_FREQ_2 = <Register.IF_FREQ_2: 47>
IF_FREQ_1 = <Register.IF_FREQ_1: 48>
DETECT_OPTIMIZE = <Register.DETECT_OPTIMIZE: 49>
INVERT_IQ = <Register.INVERT_IQ: 51>
HIGH_BW_OPTIMIZE_1 = <Register.HIGH_BW_OPTIMIZE_1: 54>
DETECTION_THRESHOLD = <Register.DETECTION_THRESHOLD: 55>
SYNC_WORD = <Register.SYNC_WORD: 57>
HIGH_BW_OPTIMIZE_2 = <Register.HIGH_BW_OPTIMIZE_2: 58>
INVERT_IQ_2 = <Register.INVERT_IQ_2: 59>
IMAGE_CAL = <Register.INVERT_IQ_2: 59>
DIO_MAPPING_1 = <Register.DIO_MAPPING_1: 64>
DIO_MAPPING_2 = <Register.DIO_MAPPING_2: 65>
VERSION = <Register.VERSION: 66>
TCXO = <Register.TCXO: 75>
PA_DAC = <Register.PA_DAC: 77>
SpuriousReception = <class 'builtins.Sx127xSpuriousReception'>
TxPower = <class 'builtins.Sx127xTxPower'>
def automatic_if(current: int, on: bool) -> int:
457def automatic_if(current: int, on: bool) -> int:
458    """Return RegDetectOptimize with AutomaticIFOn set or clear.
459
460    :param current: The register's current value.
461    :param on: Whether the automatic IF stays on.
462    :returns: The register value.
463    """
464    return _automatic_if(current, on)

Return RegDetectOptimize with AutomaticIFOn set or clear.

Parameters
  • current: The register's current value.
  • on: Whether the automatic IF stays on. :returns: The register value.
def frequency_from_word(word: int) -> int:
294def frequency_from_word(word: int) -> int:
295    """Return the frequency a RegFrf word selects.
296
297    :param word: The 24-bit frequency word.
298    :returns: The carrier frequency in hertz.
299    """
300    return _frequency_from_word(word)

Return the frequency a RegFrf word selects.

Parameters
  • word: The 24-bit frequency word. :returns: The carrier frequency in hertz.
def frequency_word(frequency_hz: int) -> int:
282def frequency_word(frequency_hz: int) -> int:
283    """Return the 24-bit RegFrf word for a frequency.
284
285    :param frequency_hz: The carrier frequency in hertz.
286    :returns: The frequency times 2^19 over the 32 MHz crystal, rounded to the nearest step.
287
288    >>> hex(frequency_word(868_100_000))
289    '0xd90666'
290    """
291    return _frequency_word(frequency_hz)

Return the 24-bit RegFrf word for a frequency.

Parameters
  • frequency_hz: The carrier frequency in hertz. :returns: The frequency times 2^19 over the 32 MHz crystal, rounded to the nearest step.
>>> hex(frequency_word(868_100_000))
'0xd90666'
def fsk_op_mode(mode: Mode | str) -> int:
331def fsk_op_mode(mode: Mode | str) -> int:
332    """Return the RegOpMode value for an FSK operating mode, which image calibration needs.
333
334    :param mode: The operating mode.
335    :returns: The register value.
336    :raises ValueError: If no mode goes by that name.
337    """
338    return _fsk_op_mode(Mode(mode).value)

Return the RegOpMode value for an FSK operating mode, which image calibration needs.

Parameters
  • mode: The operating mode. :returns: The register value.
Raises
  • ValueError: If no mode goes by that name.
def high_bw_optimize(link: LoraLink, frequency_hz: int) -> Sx127xHighBwOptimize:
427def high_bw_optimize(link: LoraLink, frequency_hz: int) -> HighBwOptimize:
428    """Return the writes of the 500 kHz sensitivity erratum.
429
430    :param link: The link settings, whose bandwidth decides.
431    :param frequency_hz: The carrier frequency in hertz.
432    :returns: RegHighBwOptimize1 and, where it is written, RegHighBwOptimize2.
433    :raises PamojaError: If the SX127x has no such bandwidth.
434    """
435    return _high_bw_optimize(link, frequency_hz)

Return the writes of the 500 kHz sensitivity erratum.

Parameters
  • link: The link settings, whose bandwidth decides.
  • frequency_hz: The carrier frequency in hertz. :returns: RegHighBwOptimize1 and, where it is written, RegHighBwOptimize2.
Raises
  • PamojaError: If the SX127x has no such bandwidth.
def image_cal_start(current: int) -> int:
448def image_cal_start(current: int) -> int:
449    """Return RegImageCal to start a calibration.
450
451    :param current: The register's current value.
452    :returns: The value with ImageCalStart set and AutoImageCalOn clear.
453    """
454    return _image_cal_start(current)

Return RegImageCal to start a calibration.

Parameters
  • current: The register's current value. :returns: The value with ImageCalStart set and AutoImageCalOn clear.
def invert_iq(receive: bool, transmit: bool) -> int:
407def invert_iq(receive: bool, transmit: bool) -> int:
408    """Return RegInvertIQ for the IQ polarity of each path.
409
410    :param receive: Whether to invert the receive path, as a LoRaWAN device does for downlinks.
411    :param transmit: Whether to invert the transmit path, as a gateway does.
412    :returns: The register value, with the transmit bit set for normal IQ as the reference
413        drivers have it.
414    """
415    return _invert_iq(receive, transmit)

Return RegInvertIQ for the IQ polarity of each path.

Parameters
  • receive: Whether to invert the receive path, as a LoRaWAN device does for downlinks.
  • transmit: Whether to invert the transmit path, as a gateway does. :returns: The register value, with the transmit bit set for normal IQ as the reference drivers have it.
def invert_iq_2(inverted: bool) -> int:
418def invert_iq_2(inverted: bool) -> int:
419    """Return RegInvertIQ2 for the path in use.
420
421    :param inverted: Whether that path is inverted.
422    :returns: 0x19 when inverted, else 0x1D.
423    """
424    return _invert_iq_2(inverted)

Return RegInvertIQ2 for the path in use.

Parameters
  • inverted: Whether that path is inverted. :returns: 0x19 when inverted, else 0x1D.
def lora_op_mode(mode: Mode | str) -> int:
321def lora_op_mode(mode: Mode | str) -> int:
322    """Return the RegOpMode value for a LoRa operating mode.
323
324    :param mode: The operating mode.
325    :returns: The register value, with the LoRa register page selected.
326    :raises ValueError: If no mode goes by that name.
327    """
328    return _lora_op_mode(Mode(mode).value)

Return the RegOpMode value for a LoRa operating mode.

Parameters
  • mode: The operating mode. :returns: The register value, with the LoRa register page selected.
Raises
  • ValueError: If no mode goes by that name.
def mode_from_op_mode(op_mode: int) -> Mode:
341def mode_from_op_mode(op_mode: int) -> Mode:
342    """Return the operating mode a RegOpMode value holds.
343
344    :param op_mode: The register value.
345    :returns: The mode.
346    """
347    return Mode(_mode_from_op_mode(op_mode))

Return the operating mode a RegOpMode value holds.

Parameters
  • op_mode: The register value. :returns: The mode.
def modem( link: LoraLink, frequency_hz: int, symbol_timeout: int = 0) -> Sx127xModem:
350def modem(link: LoraLink, frequency_hz: int, symbol_timeout: int = 0) -> Modem:
351    """Return the LoRa modem registers for a link at a carrier.
352
353    :param link: The link settings.
354    :param frequency_hz: The carrier frequency, which rules out 250 and 500 kHz below 175 MHz.
355    :param symbol_timeout: A single reception timeout in symbols, whose top bits go in
356        RegModemConfig2.
357    :returns: RegModemConfig1 to 3 and the SF6 detection settings.
358    :raises PamojaError: If the SX127x cannot use the link at the carrier.
359    """
360    return _modem(link, frequency_hz, symbol_timeout)

Return the LoRa modem registers for a link at a carrier.

Parameters
  • link: The link settings.
  • frequency_hz: The carrier frequency, which rules out 250 and 500 kHz below 175 MHz.
  • symbol_timeout: A single reception timeout in symbols, whose top bits go in RegModemConfig2. :returns: RegModemConfig1 to 3 and the SF6 detection settings.
Raises
  • PamojaError: If the SX127x cannot use the link at the carrier.
def modem_status(byte: int) -> Sx127xModemStatus:
488def modem_status(byte: int) -> ModemStatus:
489    """Decode RegModemStat.
490
491    :param byte: The register value.
492    :returns: The modem's live state.
493    """
494    return _modem_status(byte)

Decode RegModemStat.

Parameters
  • byte: The register value. :returns: The modem's live state.
def ocp_register(milliamps: int) -> int:
398def ocp_register(milliamps: int) -> int:
399    """Return RegOcp for a current limit.
400
401    :param milliamps: The most current the amplifier may draw.
402    :returns: The register value with the protection on.
403    """
404    return _ocp_register(milliamps)

Return RegOcp for a current limit.

Parameters
  • milliamps: The most current the amplifier may draw. :returns: The register value with the protection on.
def packet_status(answer: bytes, frequency_hz: int) -> Sx127xPacketStatus:
467def packet_status(answer: bytes, frequency_hz: int) -> PacketStatus:
468    """Decode RegPktSnrValue and RegPktRssiValue, read together.
469
470    :param answer: The two register values, SNR first.
471    :param frequency_hz: The carrier the packet was heard at, which picks the RF port's offset.
472    :returns: The three signal levels, exact to a hundredth of a decibel.
473    :raises ValueError: If the answer is not two bytes.
474    """
475    return _packet_status(bytes(answer), frequency_hz)

Decode RegPktSnrValue and RegPktRssiValue, read together.

Parameters
  • answer: The two register values, SNR first.
  • frequency_hz: The carrier the packet was heard at, which picks the RF port's offset. :returns: The three signal levels, exact to a hundredth of a decibel.
Raises
  • ValueError: If the answer is not two bytes.
def read_address(address: int) -> int:
303def read_address(address: int) -> int:
304    """Return the address byte that reads a register.
305
306    :param address: The register address.
307    :returns: The address with the write bit clear.
308    """
309    return _read_address(address)

Return the address byte that reads a register.

Parameters
  • address: The register address. :returns: The address with the write bit clear.
def rssi_dbm(byte: int, frequency_hz: int) -> float:
478def rssi_dbm(byte: int, frequency_hz: int) -> float:
479    """Decode RegRssiValue.
480
481    :param byte: The register value.
482    :param frequency_hz: The carrier the receiver is tuned to.
483    :returns: The signal power the receiver hears right now, in dBm.
484    """
485    return _rssi_dbm(byte, frequency_hz)

Decode RegRssiValue.

Parameters
  • byte: The register value.
  • frequency_hz: The carrier the receiver is tuned to. :returns: The signal power the receiver hears right now, in dBm.
def spurious_reception(link: LoraLink) -> Sx127xSpuriousReception:
438def spurious_reception(link: LoraLink) -> SpuriousReception:
439    """Return the receive settings of the spurious reception erratum.
440
441    :param link: The link settings, whose bandwidth decides.
442    :returns: The automatic IF, the hand-set IF, and the carrier offset.
443    :raises PamojaError: If the SX127x has no such bandwidth.
444    """
445    return _spurious_reception(link)

Return the receive settings of the spurious reception erratum.

Parameters
  • link: The link settings, whose bandwidth decides. :returns: The automatic IF, the hand-set IF, and the carrier offset.
Raises
  • PamojaError: If the SX127x has no such bandwidth.
def symbol_timeout(link: LoraLink, timeout_us: int) -> int:
363def symbol_timeout(link: LoraLink, timeout_us: int) -> int:
364    """Return a single reception timeout in the link's symbols.
365
366    :param link: The link settings, whose symbol time counts the timeout.
367    :param timeout_us: How long to listen for a preamble, in microseconds.
368    :returns: The timeout rounded up to whole symbols, from 4 to 1023.
369    """
370    return _symbol_timeout(link, timeout_us)

Return a single reception timeout in the link's symbols.

Parameters
  • link: The link settings, whose symbol time counts the timeout.
  • timeout_us: How long to listen for a preamble, in microseconds. :returns: The timeout rounded up to whole symbols, from 4 to 1023.
def tx_power( output: PaOutput | str, output_dbm: int) -> Sx127xTxPower:
373def tx_power(output: PaOutput | str, output_dbm: int) -> TxPower:
374    """Choose the amplifier settings for an output power.
375
376    :param output: The amplifier output the module uses.
377    :param output_dbm: The output power wanted, in dBm.
378    :returns: The settings, clamped to what the output delivers.
379    :raises ValueError: If no output goes by that name.
380    """
381    return _tx_power(PaOutput(output).value, output_dbm)

Choose the amplifier settings for an output power.

Parameters
  • output: The amplifier output the module uses.
  • output_dbm: The output power wanted, in dBm. :returns: The settings, clamped to what the output delivers.
Raises
  • ValueError: If no output goes by that name.
def tx_power_under_ceiling( output: PaOutput | str, budget: LinkBudget, eirp_ceiling_dbm: float) -> Sx127xTxPower:
384def tx_power_under_ceiling(
385    output: PaOutput | str, budget: LinkBudget, eirp_ceiling_dbm: float
386) -> TxPower:
387    """Choose the amplifier settings that keep a link's EIRP at or under a ceiling.
388
389    :param output: The amplifier output the module uses.
390    :param budget: The link budget, whose transmitting antenna and cable apply.
391    :param eirp_ceiling_dbm: The EIRP limit in dBm.
392    :returns: The settings, rounded down to whole decibels.
393    :raises ValueError: If no output goes by that name.
394    """
395    return _tx_power_under_ceiling(PaOutput(output).value, budget, eirp_ceiling_dbm)

Choose the amplifier settings that keep a link's EIRP at or under a ceiling.

Parameters
  • output: The amplifier output the module uses.
  • budget: The link budget, whose transmitting antenna and cable apply.
  • eirp_ceiling_dbm: The EIRP limit in dBm. :returns: The settings, rounded down to whole decibels.
Raises
  • ValueError: If no output goes by that name.
def write_address(address: int) -> int:
312def write_address(address: int) -> int:
313    """Return the address byte that writes a register.
314
315    :param address: The register address.
316    :returns: The address with the write bit set.
317    """
318    return _write_address(address)

Return the address byte that writes a register.

Parameters
  • address: The register address. :returns: The address with the write bit set.