|
@@ -109,6 +109,16 @@ class _ReceivedPacket: # unstable
|
|
|
)
|
|
|
|
|
|
|
|
|
+def _format_patable(settings: typing.Iterable[int], insert_spaces: bool) -> str:
|
|
|
+ # "Table 39: Optimum PATABLE Settings" uses hexadecimal digits
|
|
|
+ # "0" for brevity
|
|
|
+ settings_hex = tuple(map(lambda s: "0" if s == 0 else "0x{:x}".format(s), settings))
|
|
|
+ if len(settings_hex) == 1:
|
|
|
+ return "({},)".format(settings_hex[0])
|
|
|
+ delimiter = ", " if insert_spaces else ","
|
|
|
+ return "({})".format(delimiter.join(settings_hex))
|
|
|
+
|
|
|
+
|
|
|
class CC1101:
|
|
|
|
|
|
# pylint: disable=too-many-public-methods
|
|
@@ -489,6 +499,7 @@ class CC1101:
|
|
|
> If OOK modulation is used, the logic 0 and logic 1 power levels
|
|
|
> shall be programmed to index 0 and 1 respectively.
|
|
|
"""
|
|
|
+ assert 0 <= setting_index <= 0b111, setting_index
|
|
|
frend0 = self._read_single_byte(ConfigurationRegisterAddress.FREND0)
|
|
|
frend0 &= 0b11111000
|
|
|
frend0 |= setting_index
|
|
@@ -664,8 +675,8 @@ class CC1101:
|
|
|
else "=",
|
|
|
self.get_packet_length_bytes(),
|
|
|
),
|
|
|
- "output_power_levels=({})".format(
|
|
|
- "".join(map("0x{:X},".format, self.get_output_power_levels()))
|
|
|
+ "output_power={}".format(
|
|
|
+ _format_patable(self.get_output_power(), insert_spaces=False)
|
|
|
),
|
|
|
)
|
|
|
return "CC1101({})".format(", ".join(filter(None, attrs)))
|
|
@@ -803,22 +814,42 @@ class CC1101:
|
|
|
)
|
|
|
)
|
|
|
|
|
|
- def _set_patable(self, setting: typing.Iterable[int]):
|
|
|
- setting = list(setting)
|
|
|
- assert 0 < len(setting) <= self._PATABLE_LENGTH_BYTES, setting
|
|
|
- self._write_burst(start_register=PatableAddress.PATABLE, values=setting)
|
|
|
+ def _set_patable(self, settings: typing.Iterable[int]):
|
|
|
+ settings = list(settings)
|
|
|
+ assert all(0 <= l <= 0xFF for l in settings), settings
|
|
|
+ assert 0 < len(settings) <= self._PATABLE_LENGTH_BYTES, settings
|
|
|
+ self._write_burst(start_register=PatableAddress.PATABLE, values=settings)
|
|
|
|
|
|
- def get_output_power_levels(self) -> typing.Tuple[int, ...]:
|
|
|
+ def get_output_power(self) -> typing.Tuple[int, ...]:
|
|
|
"""
|
|
|
- Returns the enabled PATABLE output power levels (up to 8 bytes).
|
|
|
+ Returns the enabled output power settings
|
|
|
+ (up to 8 bytes of the PATABLE register).
|
|
|
+
|
|
|
+ see .set_output_power()
|
|
|
+ """
|
|
|
+ return self._get_patable()[: self._get_power_amplifier_setting_index() + 1]
|
|
|
+
|
|
|
+ def set_output_power(self, power_settings: typing.Iterable[int]) -> None:
|
|
|
+ """
|
|
|
+ Configures output power levels by setting PATABLE and FREND0.PA_POWER.
|
|
|
+ Up to 8 bytes may be provided.
|
|
|
|
|
|
> [PATABLE] provides flexible PA power ramp up and ramp down
|
|
|
> at the start and end of transmission when using 2-FSK, GFSK,
|
|
|
> 4-FSK, and MSK modulation as well as ASK modulation shaping.
|
|
|
|
|
|
- See "24 Output Power Programming"
|
|
|
+ For OOK modulation, exactly 2 bytes must be provided:
|
|
|
+ 0 to turn off the transmission for logical 0,
|
|
|
+ and a level > 0 to turn on the transmission for logical 1.
|
|
|
+ >>> transceiver.set_output_power((0, 0xC6))
|
|
|
+
|
|
|
+ See "Table 39: Optimum PATABLE Settings for Various Output Power Levels [...]"
|
|
|
+ and section "24 Output Power Programming".
|
|
|
"""
|
|
|
- return self._get_patable()[: self._get_power_amplifier_setting_index() + 1]
|
|
|
+ power_settings = list(power_settings)
|
|
|
+ # checks in sub-methods
|
|
|
+ self._set_power_amplifier_setting_index(len(power_settings) - 1)
|
|
|
+ self._set_patable(power_settings)
|
|
|
|
|
|
def _flush_tx_fifo_buffer(self) -> None:
|
|
|
# > Only issue SFTX in IDLE or TXFIFO_UNDERFLOW states.
|