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:
parent
9f58ad6e3e
commit
477938e46e
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user