Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 53 additions & 3 deletions drivers/cc110x/cc110x.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ int cc110x_apply_config(cc110x_t *dev, const cc110x_config_t *conf,
return cc110x_full_calibration(dev);
}

static void _set_tx_power(cc110x_t *dev, cc110x_tx_power_t power)
{
uint8_t frend0 = 0x10 | (uint8_t)power;
cc110x_write(dev, CC110X_REG_FREND0, frend0);
dev->tx_power = power;
}

int cc110x_set_tx_power(cc110x_t *dev, cc110x_tx_power_t power)
{
DEBUG("[cc110x] Applying TX power setting at index %u\n", (unsigned)power);
Expand All @@ -114,9 +121,8 @@ int cc110x_set_tx_power(cc110x_t *dev, cc110x_tx_power_t power)
return -EAGAIN;
}

uint8_t frend0 = 0x10 | (uint8_t)power;
cc110x_write(dev, CC110X_REG_FREND0, frend0);
dev->tx_power = power;
_set_tx_power(dev, power);

cc110x_release(dev);
return 0;
}
Expand Down Expand Up @@ -176,3 +182,47 @@ int cc110x_set_channel(cc110x_t *dev, uint8_t channel)
dev->netdev.event_callback(&dev->netdev, NETDEV_EVENT_FHSS_CHANGE_CHANNEL);
return 0;
}

int cc110x_wakeup(cc110x_t *dev)
{
int err = cc110x_power_on_and_acquire(dev);

if (err) {
return err;
}

/* PA_TABLE is lost on SLEEP, see 10.6 in the CC1101 data sheet */
cc110x_burst_write(dev, CC110X_MULTIREG_PATABLE,
dev->params.patable->data, CC110X_PATABLE_LEN);
_set_tx_power(dev, dev->tx_power);

cc110x_enter_rx_mode(dev);
cc110x_release(dev);
return 0;
}

void cc110x_sleep(cc110x_t *dev)
{
cc110x_acquire(dev);
if (dev->state == CC110X_STATE_OFF) {
cc110x_release(dev);
return;
}

/*
* Datasheet page 9 table 4.
*
* To achieve the lowest power consumption GDO's must
* be programmed to 0x2F
*/
cc110x_write(dev, CC110X_REG_IOCFG2, CC110X_GDO_CONSTANT_LOW);
cc110x_write(dev, CC110X_REG_IOCFG1, CC110X_GDO_CONSTANT_LOW);
cc110x_write(dev, CC110X_REG_IOCFG0, CC110X_GDO_CONSTANT_LOW);

/* transition to SLEEP only from state IDLE possible */
cc110x_cmd(dev, CC110X_STROBE_IDLE);
/* go to SLEEP */
cc110x_cmd(dev, CC110X_STROBE_OFF);
dev->state = CC110X_STATE_OFF;
cc110x_release(dev);
}
21 changes: 17 additions & 4 deletions drivers/cc110x/cc110x_communication.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,36 @@
*/

#include <errno.h>

#include "cc110x.h"
#include "cc110x_communication.h"
#include "cc110x_constants.h"
#include "cc110x_internal.h"
#include "periph/gpio.h"
#include "periph/spi.h"
#include "xtimer.h"
#include "cc110x.h"
#include "cc110x_constants.h"

int cc110x_power_on(cc110x_t *dev)
int cc110x_power_on_and_acquire(cc110x_t *dev)
{
gpio_t cs = dev->params.cs;

if (gpio_init(cs, GPIO_OUT)) {
return -EIO;
}
gpio_clear(cs);
xtimer_usleep(150);
xtimer_usleep(CC110X_WAKEUP_TIME_US);
gpio_set(cs);
spi_init_cs(dev->params.spi, dev->params.cs);

if (cc110x_acquire(dev) != SPI_OK) {
return -EIO;
}

while (cc110x_state_from_status(cc110x_status(dev)) != CC110X_STATE_IDLE) {
cc110x_cmd(dev, CC110X_STROBE_IDLE);
xtimer_usleep(CC110X_WAKEUP_TIME_US);
}

return 0;
}

Expand Down
Loading