1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers/mrf24j40: add external PA/LNA control on MC/MD/ME devices

The MRF24J40MC/MD/ME modules contain an external power amplifier &
low noise amplifier that has to be enabled manually by setting three bits
in the TESTMODE register.
On MRF24J40MC the power amplifier is powered by a separate voltage regualtor
that has to be enabled by setting GPIO3 to HIGH.

During Sleep and CCA the PA should be disabled.

Co-authored-by: Carton <joel.carron@eeproperty.ch>
Co-authored-by: Benjamin Valentin <benjamin.valentin@ml-pa.com>
This commit is contained in:
Benjamin Valentin 2019-04-15 16:16:55 +02:00
parent 9f58ad6e3e
commit 477938e46e
6 changed files with 137 additions and 0 deletions

View File

@ -115,6 +115,16 @@ extern "C" {
#define MRF24J40_MAX_FRAME_RETRIES (3U) /**< Number of frame retries (fixed) */
/**
* @brief Enable external PA/LNA control
*
* Increase RSSI for MRF24J40MC/MD/ME devices. No effect on MRF24J40MA.
* For more information, please refer to section 4.2 of MRF24J40 datasheet.
*/
#ifndef MRF24J40_USE_EXT_PA_LNA
#define MRF24J40_USE_EXT_PA_LNA (0U)
#endif
/**
* @brief struct holding all params needed for device initialization
*/

View File

@ -114,6 +114,39 @@ void mrf24j40_update_tasks(mrf24j40_t *dev);
*/
void mrf24j40_hardware_reset(mrf24j40_t *dev);
/**
* @brief Enable automatic External Power Amplifier & Low Noise Amplifier control
*
* @param[in] dev device to enable the PA & LNA on
*/
#if MRF24J40_USE_EXT_PA_LNA
void mrf24j40_enable_auto_pa_lna(mrf24j40_t *dev);
#else
static inline void mrf24j40_enable_auto_pa_lna(mrf24j40_t *dev) { (void) dev; }
#endif
/**
* @brief Disable automatic External Power Amplifier & Low Noise Amplifier control
*
* @param[in] dev device to disable the PA & LNA on
*/
#if MRF24J40_USE_EXT_PA_LNA
void mrf24j40_disable_auto_pa_lna(mrf24j40_t *dev);
#else
static inline void mrf24j40_disable_auto_pa_lna(mrf24j40_t *dev) { (void) dev; }
#endif
/**
* @brief Enable only the External Low Noise Amplifier
*
* @param[in] dev device enable the LNA on
*/
#if MRF24J40_USE_EXT_PA_LNA
void mrf24j40_enable_lna(mrf24j40_t *dev);
#else
static inline void mrf24j40_enable_lna(mrf24j40_t *dev) { (void) dev; }
#endif
#ifdef __cplusplus
}
#endif

View File

@ -326,6 +326,18 @@ extern "C" {
#define MRF24J40_INTCON_TXNIE (0x01)
/** @} */
/**
* @name Bitfield definitions for the GPIO register (0x33)
* @{
*/
#define MRF24J40_GPIO_0 (0x01)
#define MRF24J40_GPIO_1 (0x02)
#define MRF24J40_GPIO_2 (0x04)
#define MRF24J40_GPIO_3 (0x08)
#define MRF24J40_GPIO_4 (0x10)
#define MRF24J40_GPIO_5 (0x20)
/** @} */
/**
* @name Bitfield definitions for the SLPACK register (0x35)
* @{
@ -453,6 +465,16 @@ extern "C" {
#define MRF24J40_SLPCON1_SLPCLKDIV0 (0x01)
/** @} */
/**
* @name Bitfield definitions for the TESTMODE register (0x22F)
* @{
*/
#define MRF24J40_TESTMODE_RSSIWAIT1 (0x10)
#define MRF24J40_TESTMODE_RSSIWAIT0 (0x08)
#define MRF24J40_TESTMODE_TESTMODE2 (0x04)
#define MRF24J40_TESTMODE_TESTMODE1 (0x02)
#define MRF24J40_TESTMODE_TESTMODE0 (0x01)
/** @} */
#ifdef __cplusplus
}

View File

@ -81,6 +81,7 @@ bool mrf24j40_cca(mrf24j40_t *dev)
uint8_t tmp_rssi;
mrf24j40_assert_awake(dev);
mrf24j40_enable_lna(dev);
/* trigger CCA measurment */
/* take a look onto datasheet chapter 3.6.1 */
@ -93,6 +94,9 @@ bool mrf24j40_cca(mrf24j40_t *dev)
/* return according to measurement */
tmp_ccaedth = mrf24j40_reg_read_short(dev, MRF24J40_REG_CCAEDTH); /* Energy detection threshold */
tmp_rssi = mrf24j40_reg_read_long(dev, MRF24J40_REG_RSSI);
mrf24j40_enable_auto_pa_lna(dev);
if (tmp_rssi < tmp_ccaedth) {
/* channel is clear */
return true; /* idle */

View File

@ -434,6 +434,9 @@ void mrf24j40_set_state(mrf24j40_t *dev, uint8_t state)
void mrf24j40_sleep(mrf24j40_t *dev)
{
DEBUG("[mrf24j40] Putting into sleep mode\n");
/* disable the PA & LNA */
mrf24j40_disable_auto_pa_lna(dev);
/* Datasheet chapter 3.15.2 IMMEDIATE SLEEP AND WAKE-UP MODE */
/* First force a Power Management Reset */
mrf24j40_reg_write_short(dev, MRF24J40_REG_SOFTRST, MRF24J40_SOFTRST_RSTPWR);
@ -467,6 +470,7 @@ void mrf24j40_assert_awake(mrf24j40_t *dev)
xtimer_usleep(MRF24J40_WAKEUP_DELAY);
/* reset interrupts */
mrf24j40_reg_read_short(dev, MRF24J40_REG_INTSTAT);
mrf24j40_enable_auto_pa_lna(dev);
dev->state = MRF24J40_PSEUDO_STATE_IDLE;
}
}

View File

@ -36,6 +36,68 @@ static inline void getbus(mrf24j40_t *dev)
spi_acquire(SPIDEV, CSPIN, SPI_MODE_0, dev->params.spi_clk);
}
#if MRF24J40_USE_EXT_PA_LNA
static inline void mrf24j40_reg_and_short(mrf24j40_t *dev, const uint8_t addr, uint8_t value)
{
value &= mrf24j40_reg_read_short(dev, addr);
mrf24j40_reg_write_short(dev, addr, value);
}
static inline void mrf24j40_reg_or_short(mrf24j40_t *dev, const uint8_t addr, uint8_t value)
{
value |= mrf24j40_reg_read_short(dev, addr);
mrf24j40_reg_write_short(dev, addr, value);
}
void mrf24j40_enable_auto_pa_lna(mrf24j40_t *dev)
{
/* Configure enable pin of the Voltage Regulator for the PA (GPIO3) on MRF24J40MC */
mrf24j40_reg_or_short(dev, MRF24J40_REG_TRISGPIO, MRF24J40_GPIO_3);
/* Enable the volate regulator to power the Power Amplifier */
mrf24j40_reg_or_short(dev, MRF24J40_REG_GPIO, MRF24J40_GPIO_3);
mrf24j40_reg_write_long(dev, MRF24J40_REG_TESTMODE, (MRF24J40_TESTMODE_RSSIWAIT0 |
MRF24J40_TESTMODE_TESTMODE2 |
MRF24J40_TESTMODE_TESTMODE1 |
MRF24J40_TESTMODE_TESTMODE0));
}
void mrf24j40_disable_auto_pa_lna(mrf24j40_t *dev)
{
/* Disable automatic switch on PA/LNA */
mrf24j40_reg_write_long(dev, MRF24J40_REG_TESTMODE, MRF24J40_TESTMODE_RSSIWAIT0);
/* Configure all GPIOs as Output */
mrf24j40_reg_or_short(dev, MRF24J40_REG_TRISGPIO, (MRF24J40_GPIO_0 |
MRF24J40_GPIO_1 |
MRF24J40_GPIO_2 |
MRF24J40_GPIO_3));
/* Disable all GPIO outputs */
mrf24j40_reg_and_short(dev, MRF24J40_REG_GPIO, ~(MRF24J40_GPIO_0 |
MRF24J40_GPIO_1 |
MRF24J40_GPIO_2 |
MRF24J40_GPIO_3));
}
void mrf24j40_enable_lna(mrf24j40_t *dev)
{
/* Disable automatic switch on PA/LNA */
mrf24j40_reg_write_long(dev, MRF24J40_REG_TESTMODE, MRF24J40_TESTMODE_RSSIWAIT0);
/* Configure all GPIOs as Output */
mrf24j40_reg_or_short(dev, MRF24J40_REG_TRISGPIO, (MRF24J40_GPIO_0 |
MRF24J40_GPIO_1 |
MRF24J40_GPIO_2 |
MRF24J40_GPIO_3));
/* Enable LNA, keep PA voltage regulator on */
mrf24j40_reg_and_short(dev, MRF24J40_REG_GPIO, ~(MRF24J40_GPIO_0 | MRF24J40_GPIO_1));
mrf24j40_reg_or_short(dev, MRF24J40_REG_GPIO, MRF24J40_GPIO_2 | MRF24J40_GPIO_3);
}
#endif /* MRF24J40_USE_EXT_PA_LNA */
void mrf24j40_init(mrf24j40_t *dev)
{
@ -88,6 +150,8 @@ void mrf24j40_init(mrf24j40_t *dev)
mrf24j40_reg_write_short(dev, MRF24J40_REG_CCAEDTH, 0x60);
mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG6, MRF24J40_BBREG6_RSSIMODE2 );
mrf24j40_enable_auto_pa_lna(dev);
/* Enable immediate sleep mode */
mrf24j40_reg_write_short(dev, MRF24J40_REG_WAKECON, MRF24J40_WAKECON_IMMWAKE);