Arduino LMIC 6.0.1
Arduino LoRaWAN(r) MAC in C
Loading...
Searching...
No Matches
radio_sx127x.c File Reference

Radio driver for radios based on SX1272/SX1276 chips. More...

Include dependency graph for radio_sx127x.c:

Functions

void os_radio_v2 (u1_t mode, osjob_t *pJob)
 Initiate a radio operation.
int radio_init ()
 Initialize radio at system startup.
void radio_irq_handler (u1_t dio)
 legacy radio IRQ handler
void radio_irq_handler_v2 (u1_t dio, ostime_t now)
 Radio IRQ handler.
void radio_monitor_rssi (ostime_t nTicks, oslmic_radio_rssi_t *pRssi)
 Measure the current broadband RSSI for the current channel.
u1_t radio_rand1 ()
 Generate an 8-bit uniformly-distributed integer.

Detailed Description

Radio driver for radios based on SX1272/SX1276 chips.

Function Documentation

◆ os_radio_v2()

void os_radio_v2 ( u1_t mode,
osjob_t * pJob )

Initiate a radio operation.

Parameters
mode[in] Selects the operation to be performed.
pJob[inout] Job to be scheduled when operation completes.

The requested radio operation is initiated. Some operations complete immediately; others require hardware to do work, and don't complete until an interrupt occurs. In that case, pJob is scheduled. Because the interrupt may occur right away, it's important that the caller initialize pJob before calling this routine.

  • RADIO_RST causes the radio to be put to sleep. No interrupt follows; when control returns, the radio is ready for the next operation. pJob is not scheduled. If an operation was pending, it is canceled.
  • RADIO_TX and RADIO_TX_AT launch the transmission of a frame. An interrupt will occur, which will cause pJob to be scheduled with its current function.
  • RADIO_RX, RADIO_RX_ON and RADIO_RX_ON_C launch either timed or untimed receives. An interrupt will occur when a packet is recieved or the receive times out, which will cause pJob to be scheduled with its current function. RADIO_RX_ON_C is used to schedule a request that might be redundat, for class C support.
Note
It's a quirk of the implementation that timeouts may be handled by the very same pJob that we use for completion. os_setCallback() cancels any previous operation for the job. It's all a little fragile, because most callers use the exact same LMIC.osjob object that is used for other purposes throughout the LMIC.

References LMIC_RADIO_EV_NONE, LMIC_RADIO_EV_RXSTART, LMIC_RADIO_EV_TXSTART, RADIO_RST, RADIO_RX, RADIO_RXON, RADIO_RXON_C, RADIO_TX, and RADIO_TX_AT.

◆ radio_init()

int radio_init ( void )

Initialize radio at system startup.

This procedure is called during initialization by the os_init() routine. It does a hardware reset of the radio, checks the version and confirms that we're operating a suitable chip, and gets a random seed from wideband noise rssi. It then puts the radio to sleep.

Returns
True if successful, false if it doesn't look like the right radio is attached.
Precondition

Preconditions must be observed, or you'll get hangs during initialization.

  • The lmic_hal_pin_..() functions must be ready for use.
  • The lmic_hal_waitUntl() function must be ready for use. This may mean that interrupts are enabled.
  • The lmic_hal_spi_..() functions must be ready for use.

Generally, all these are satisfied by a call to lmic_hal_init_with_pinmap().

◆ radio_irq_handler()

void radio_irq_handler ( u1_t dio)

legacy radio IRQ handler

Parameters
[in]diois the image of the DIO0..n pins observed by the primary ISR.

The HAL is responsible for detecting transitions on the SX127x DIO pins, and scheduling this routine. This routine must run as part of os_runloop_once(); it must not be called directly from a primary ISR.

This routine is for legacy use only; it is for use by older HALs that cannot capture the interrupt time in the primary ISR.

See also
radio_irq_handler_v2

References radio_irq_handler_v2().

◆ radio_irq_handler_v2()

void radio_irq_handler_v2 ( u1_t dio,
ostime_t now )

Radio IRQ handler.

Parameters
[in]diois the image of the DIO0..n pins observed by the primary ISR.
[in]nowis the HALs best estimate of the time of teh interrupt.

The HAL is responsible for detecting transitions on the SX127x DIO pins, and scheduling this routine. This routine must run as part of os_runloop_once(); it must not be called directly from a primary ISR.

The radio registers are interrogated, and the interrupt is processed. The radio is then put back to sleep, and the background is scheduled.

Note
If continuous transmit mode is configured, then this routine immediately schedules a new transmit, and never completes to the background.
See also
radio_irq_handler_v2

References LMIC_RADIO_EV_NONE, LMIC_RADIO_EV_RXDONE, LMIC_RADIO_EV_RXTIMEOUT, LMIC_RADIO_EV_RXUNKNOWN, LMIC_RADIO_EV_TXDONE, and LMIC_RADIO_EV_TXUNKNOWN.

Referenced by radio_irq_handler().

◆ radio_monitor_rssi()

void radio_monitor_rssi ( ostime_t nTicks,
oslmic_radio_rssi_t * pRssi )

Measure the current broadband RSSI for the current channel.

This funtion monitors RSSI for specified number of ostime_t ticks, and return statistics. It first puts the radio into RX continuous mode, waits long enough for the oscillators to start and the PLL to lock, and then measures for the specified period of time. The radio is then returned to idle.

Returns
RSSI expressed in units of dB, offset according to the current radio setting per section 5.5.5 of Semtech 1276 datasheet.
Parameters
nTicksHow long to monitor
pRssipointer to structure to fill in with RSSI data.

◆ radio_rand1()

u1_t radio_rand1 ( void )

Generate an 8-bit uniformly-distributed integer.

If there are any bytes remaining in the random buffer, the next byte is returned. Otherwise, sixteen new random bytes are generated, and the first is returned.

Implmementation Notes:
Originaly, the seed buffer was held in the static randbuf[], which is initialized with RSSI noise measurements during initialization. Each time we run out of data, the buffer is used to generate a new key. Formerly we used "any key" but with the reorganization of the code, there's no dedicated key buffer. So instead, we save the seed, and do a CSPRNG using AES in counter mode. Since (in any case) we immediately return the first byte of the buffer, we can replace the first byte with a buffer index, ranging from 1 to 16, which helps us to dole out the data.

References os_wlsbf4().