Skip to content

Commit

Permalink
Merge pull request #319 from mcci-catena/issue46
Browse files Browse the repository at this point in the history
Fix matthijskooijman#46: make Tx Pwr policy explicit; see matthijskooijman#300 (WIP). Also fix matthijskooijman#261, matthijskooijman#262, #321, and matthijskooijman#263.
  • Loading branch information
terrillmoore authored Jun 23, 2019
2 parents 9f01615 + 85fa717 commit 76a8f4c
Show file tree
Hide file tree
Showing 6 changed files with 341 additions and 38 deletions.
60 changes: 57 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ requires C99 mode to be enabled by default.
- [RXTX](#rxtx)
- [RXTX Polarity](#rxtx-polarity)
- [Pin mapping](#pin-mapping)
- [Advanced initialization](#advanced-initialization)
- [HalConfiguration_t methods](#halconfiguration_t-methods)
- [LoRa Nexus by Ideetron](#lora-nexus-by-ideetron)
- [Example Sketches](#example-sketches)
- [Timing](#timing)
Expand Down Expand Up @@ -521,9 +523,9 @@ We have details for the following manually-configured boards here:

- [LoRa Nexus by Ideetron](#lora-nexus-by-ideetron)

If you don't have the board documentation, you need to provide your own `lmic_pinmap` values. As described above, a variety of configurations are possible. To tell the LMIC library how your board is configured, you must declare a variable containing a pin mapping struct in the sketch file.
If your board is not configured, you need at least to provide your own `lmic_pinmap`. As described above, a variety of configurations are possible. To tell the LMIC library how your board is configured, you must declare a variable containing a pin mapping struct in your sketch file. If you call `os_init()` to initialize the LMIC, you must name this structure `lmic_pins`. If you call `os_init_ex()`, you may name the structure what you like, but you pass a pointer as the parameter to `os_init_ex()`.

For example, this could look like this:
Here's an example of a simple initialization:

```c++
lmic_pinmap lmic_pins = {
Expand Down Expand Up @@ -552,7 +554,59 @@ respectively. Any pins that are not needed should be specified as
potentially left out (depending on the environments and requirements,
see the notes above for when a pin can or cannot be left out).
The name of the variable containing this struct must always be `lmic_pins`, which is a special name recognized by the library.
#### Advanced initialization
In some boards require much more advanced management. The LMIC has a very flexible framework to support this, but it requires you to do some C++ work.
1. You must define a new class derived from `Arduino_LMIC::HalConfiguration_t`. (We'll call this `cMyHalConfiguration_t`).
2. This class *may* define overrides for several methods (discussed below).
3. You must create an instance of your class, e.g.
```c++
cMyHalConfiguration_t myHalConfigInstance;
```
4. You add another entry in your `lmic_pinmap`, `pConfig = &myHalConfigInstance`, to link your pinmap to your object.
The full example looks like this:
```c++
class cMyHlaConfiguration_t : public Arduino_LMIC::HalConfiguration_t
{
public:
// ...
// put your method function override declarations here.
// this example uses RFO at 10 dBm or less, PA_BOOST up to 17 dBm,
// or the high-power mode above 17 dBm. In other words, it lets the
// LMIC-determined policy determine what's to be done.
virutal TxPowerPolicy_t getTxPowerPolicy(
TxPowerPolicy_t policy,
int8_t requestedPower,
uint32_t frequency
) override
{
return policy;
}
}
```

#### HalConfiguration_t methods

- `ostime_t setModuleActive(bool state)` is called by the LMIC to make the module active or to deactivate it (the value of `state` is true to activate). The implementation must turn power to the module on and otherwise prepare for it to go to work, and must return the number of OS ticks to wait before starting to use the radio.

- `void begin(void)` is called during intialization, and is your code's chance to do any early setup.

- `void end(void)` is (to be) called during late shutdown. (Late shutdown is not implemented yet; but we wanted to add the API for consistency.)

- `bool queryUsingTcxo(void)` shall return `true` if the module uses a TCXO; `false` otherwise.

- `TxPowerPolicy_t getTxPowerPolicy(TxPowerPolicy_t policy, int8_t requestedPower, uint32_t frequency)` allows you to override the LMIC's selection of transmit power. If not provided, the default method forces the LMIC to use PA_BOOST mode. (We chose to do this becuase we found empirically that the Hope RF module doesn't support RFO, and because legacy LMIC code never used anything except PA_BOOST mode.)

Caution: the LMIC has no way of knowing whether the mode you return makes sense. Use of 20 dBm mode without limiting duty cycle can over-stress your module. The LMIC currently does not have any code to duty-cycle US transmissions at 20 dBm. If properly limiting transmissions to 400 ms, 1% duty-cycle means at most one message every 40 seconds. This shoudln't be a problem in practice, but buggy upper level software still might do things more rapidly.

<!-- there are links to the following section, so be careful when renaming -->
#### LoRa Nexus by Ideetron
Expand Down
24 changes: 23 additions & 1 deletion src/arduino_lmic_hal_configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ struct HalPinmap_t {
// Must include noise guardband!
uint32_t spi_freq; // bytes 8..11: SPI freq in Hz.

// optional pointer to configuration object (byest 12..15)
// optional pointer to configuration object (bytes 12..15)
HalConfiguration_t *pConfig;
};

Expand All @@ -71,6 +71,14 @@ class HalConfiguration_t
public:
HalConfiguration_t() {};

// these must match the constants in radio.c
enum class TxPowerPolicy_t : uint8_t
{
RFO,
PA_BOOST,
PA_BOOST_20dBm
};

virtual ostime_t setModuleActive(bool state) {
LMIC_API_PARAMETER(state);

Expand All @@ -83,6 +91,20 @@ class HalConfiguration_t
virtual void begin(void) {}
virtual void end(void) {}
virtual bool queryUsingTcxo(void) { return false; }

// compute desired transmit power policy. HopeRF needs
// (and previous versions of this library always chose)
// PA_BOOST mode. So that's our default. Override this
// for the Murata module.
virtual TxPowerPolicy_t getTxPowerPolicy(
TxPowerPolicy_t policy,
int8_t requestedPower,
uint32_t frequency
)
{
// default: use PA_BOOST exclusively
return TxPowerPolicy_t::PA_BOOST;
}
};

bool hal_init_with_pinmap(const HalPinmap_t *pPinmap);
Expand Down
14 changes: 13 additions & 1 deletion src/hal/hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,4 +424,16 @@ ostime_t hal_setModuleActive (bit_t val) {

bit_t hal_queryUsingTcxo(void) {
return pHalConfig->queryUsingTcxo();
}
}

uint8_t hal_getTxPowerPolicy(
u1_t inputPolicy,
s1_t requestedPower,
u4_t frequency
) {
return (uint8_t) pHalConfig->getTxPowerPolicy(
Arduino_LMIC::HalConfiguration_t::TxPowerPolicy_t(inputPolicy),
requestedPower,
frequency
);
}
19 changes: 19 additions & 0 deletions src/lmic/hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,27 @@ s1_t hal_getRssiCal (void);
*/
ostime_t hal_setModuleActive (bit_t val);

/* find out if we're using Tcxo */
bit_t hal_queryUsingTcxo(void);

/* represent the various radio TX power policy */
enum {
LMICHAL_radio_tx_power_policy_rfo = 0,
LMICHAL_radio_tx_power_policy_paboost = 1,
LMICHAL_radio_tx_power_policy_20dBm = 2,
};

/*
* query the configuration as to the Tx Power Policy
* to be used on this board, given our desires and
* requested power.
*/
uint8_t hal_getTxPowerPolicy(
u1_t inputPolicy,
s1_t requestedPower,
u4_t freq
);

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
6 changes: 5 additions & 1 deletion src/lmic/lmic.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,11 @@ struct lmic_t {
u1_t rxsyms;
u1_t dndr;
s1_t txpow; // transmit dBm (administrative)
s1_t radio_txpow; // the radio driver's copy of txpow, limited by adrTxPow.
s1_t radio_txpow; // the radio driver's copy of txpow, in dB limited by adrTxPow, and
// also adjusted for EIRP/antenna gain considerations.
// This is just the radio's idea of power. So if you are
// controlling EIRP, and you have 3 dB antenna gain, this
// needs to reduced by 3 dB.
s1_t lbt_dbmax; // max permissible dB on our channel (eg -80)

u1_t txChnl; // channel for next TX
Expand Down
Loading

0 comments on commit 76a8f4c

Please sign in to comment.