Exemplo n.º 1
0
int nrf24l01p_set_address_width(const nrf24l01p_t *dev, nrf24l01p_aw_t aw)
{
    char aw_setup;
    nrf24l01p_read_reg(dev, REG_SETUP_AW, &aw_setup);

    xtimer_spin(DELAY_AFTER_FUNC_TICKS);

    switch (aw) {
        case NRF24L01P_AW_3BYTE:
            aw_setup &= ~(3);
            aw_setup |= 1;
            break;

        case NRF24L01P_AW_4BYTE:
            aw_setup &= ~(3);
            aw_setup |= 2;
            break;

        case NRF24L01P_AW_5BYTE:
            aw_setup &= ~(3);
            aw_setup |= 3;
            break;

        default:
            return -1;
    }

    return nrf24l01p_write_reg(dev, REG_SETUP_AW, aw_setup);
}
Exemplo n.º 2
0
void nrf24l01p_transmit(const nrf24l01p_t *dev)
{
    gpio_set(dev->ce);
    xtimer_usleep(DELAY_CE_HIGH_US); /* at least 10 us high */
    gpio_clear(dev->ce);

    xtimer_spin(DELAY_CHANGE_TXRX_TICKS);
}
Exemplo n.º 3
0
int nrf24l01p_read_payload(nrf24l01p_t *dev, char *answer, unsigned int size)
{
    int status;

    /* Acquire exclusive access to the bus. */
    spi_acquire(dev->spi);
    gpio_clear(dev->cs);
    xtimer_spin(DELAY_CS_TOGGLE_TICKS);
    status = spi_transfer_regs(dev->spi, CMD_R_RX_PAYLOAD, 0, answer, size);
    xtimer_spin(DELAY_CS_TOGGLE_TICKS);
    gpio_set(dev->cs);
    xtimer_spin(DELAY_AFTER_FUNC_TICKS);
    /* Release the bus for other threads. */
    spi_release(dev->spi);

    return status;
}
Exemplo n.º 4
0
int nrf24l01p_set_tx_address(nrf24l01p_t *dev, char *saddr, unsigned int length)
{
    int status;

    /* Acquire exclusive access to the bus. */
    spi_acquire(dev->spi);
    gpio_clear(dev->cs);
    xtimer_spin(DELAY_CS_TOGGLE_TICKS);
    status = spi_transfer_regs(dev->spi, (CMD_W_REGISTER | (REGISTER_MASK & REG_TX_ADDR)), saddr, NULL, length); /* address width is 5 byte */
    xtimer_spin(DELAY_CS_TOGGLE_TICKS);
    gpio_set(dev->cs);
    /* Release the bus for other threads. */
    spi_release(dev->spi);

    xtimer_spin(DELAY_AFTER_FUNC_TICKS);

    return status;
}
Exemplo n.º 5
0
int nrf24l01p_read_reg(nrf24l01p_t *dev, char reg, char *answer)
{
    int status;

    /* Acquire exclusive access to the bus. */
    spi_acquire(dev->spi);
    gpio_clear(dev->cs);
    xtimer_spin(DELAY_CS_TOGGLE_TICKS);
    status = spi_transfer_reg(dev->spi, (CMD_R_REGISTER | (REGISTER_MASK & reg)), CMD_NOP, answer);
    xtimer_spin(DELAY_CS_TOGGLE_TICKS);
    gpio_set(dev->cs);
    /* Release the bus for other threads. */
    spi_release(dev->spi);

    xtimer_spin(DELAY_AFTER_FUNC_TICKS);

    return status;
}
Exemplo n.º 6
0
int nrf24l01p_read_payload(const nrf24l01p_t *dev, char *answer, unsigned int size)
{
    /* Acquire exclusive access to the bus. */
    spi_acquire(dev->spi, dev->cs, SPI_MODE, SPI_CLK);
    spi_transfer_regs(dev->spi, dev->cs, CMD_R_RX_PAYLOAD, NULL, answer, size);
    xtimer_spin(DELAY_AFTER_FUNC_TICKS);
    /* Release the bus for other threads. */
    spi_release(dev->spi);

    return 0;
}
Exemplo n.º 7
0
int nrf24l01p_preload(nrf24l01p_t *dev, char *data, unsigned int size)
{
    int status;

    size = (size <= 32) ? size : 32;

    /* Acquire exclusive access to the bus. */
    spi_acquire(dev->spi);
    gpio_clear(dev->cs);
    xtimer_spin(DELAY_CS_TOGGLE_TICKS);
    status = spi_transfer_regs(dev->spi, CMD_W_TX_PAYLOAD, data, NULL, size);
    xtimer_spin(DELAY_CS_TOGGLE_TICKS);
    gpio_set(dev->cs);
    /* Release the bus for other threads. */
    spi_release(dev->spi);

    xtimer_spin(DELAY_AFTER_FUNC_TICKS);

    return status;
}
Exemplo n.º 8
0
int nrf24l01p_write_reg(const nrf24l01p_t *dev, char reg, char write)
{
    /* Acquire exclusive access to the bus. */
    spi_acquire(dev->spi, dev->cs, SPI_MODE, SPI_CLK);
    spi_transfer_reg(dev->spi, dev->cs,
                     (CMD_W_REGISTER | (REGISTER_MASK & reg)), (uint8_t)write);
    /* Release the bus for other threads. */
    spi_release(dev->spi);

    xtimer_spin(DELAY_AFTER_FUNC_TICKS);
    return 0;
}
Exemplo n.º 9
0
int nrf24l01p_read_reg(const nrf24l01p_t *dev, char reg, char *answer)
{
    /* Acquire exclusive access to the bus. */
    spi_acquire(dev->spi, dev->cs, SPI_MODE, SPI_CLK);
    *answer = (char)spi_transfer_reg(dev->spi, dev->cs,
                                     (CMD_R_REGISTER | (REGISTER_MASK & reg)),
                                     CMD_NOP);
    /* Release the bus for other threads. */
    spi_release(dev->spi);

    xtimer_spin(DELAY_AFTER_FUNC_TICKS);
    return 0;
}
Exemplo n.º 10
0
int nrf24l01p_preload(const nrf24l01p_t *dev, char *data, unsigned int size)
{
    size = (size <= 32) ? size : 32;

    /* Acquire exclusive access to the bus. */
    spi_acquire(dev->spi, dev->cs, SPI_MODE, SPI_CLK);
    spi_transfer_regs(dev->spi, dev->cs, CMD_W_TX_PAYLOAD, data, NULL, size);
    /* Release the bus for other threads. */
    spi_release(dev->spi);

    xtimer_spin(DELAY_AFTER_FUNC_TICKS);
    return 0;
}
Exemplo n.º 11
0
int nrf24l01p_set_tx_address(const nrf24l01p_t *dev, const char *saddr, unsigned int length)
{
    /* Acquire exclusive access to the bus. */
    spi_acquire(dev->spi, dev->cs, SPI_MODE, SPI_CLK);
    spi_transfer_regs(dev->spi, dev->cs,
                      (CMD_W_REGISTER | (REGISTER_MASK & REG_TX_ADDR)),
                      saddr, NULL, length);
    /* Release the bus for other threads. */
    spi_release(dev->spi);

    xtimer_spin(DELAY_AFTER_FUNC_TICKS);

    return (int)length;
}
Exemplo n.º 12
0
static int nvram_spi_write(nvram_t *dev, uint8_t *src, uint32_t dst, size_t len)
{
    nvram_spi_params_t *spi_dev = (nvram_spi_params_t *) dev->extra;
    int status;
    union {
        uint32_t u32;
        char c[4];
    } addr;
    /* Address is expected by the device as big-endian, i.e. network byte order,
     * we utilize the network byte order macros here. */
    addr.u32 = HTONL(dst);
    /* Acquire exclusive bus access */
    spi_acquire(spi_dev->spi);
    /* Assert CS */
    gpio_clear(spi_dev->cs);
    /* Enable writes */
    status = spi_transfer_byte(spi_dev->spi, NVRAM_SPI_CMD_WREN, NULL);
    if (status < 0)
    {
        return status;
    }
    /* Release CS */
    gpio_set(spi_dev->cs);
    xtimer_spin(NVRAM_SPI_CS_TOGGLE_TICKS);
    /* Re-assert CS */
    gpio_clear(spi_dev->cs);
    /* Write command and address */
    status = spi_transfer_regs(spi_dev->spi, NVRAM_SPI_CMD_WRITE,
                      &addr.c[sizeof(addr.c) - spi_dev->address_count], NULL,
                      spi_dev->address_count);
    if (status < 0)
    {
        return status;
    }
    /* Keep holding CS and write data */
    status = spi_transfer_bytes(spi_dev->spi, (char *)src, NULL, len);
    if (status < 0)
    {
        return status;
    }
    /* Release CS */
    gpio_set(spi_dev->cs);
    /* Release exclusive bus access */
    spi_release(spi_dev->spi);
    return status;
}
Exemplo n.º 13
0
void xtimer_set(xtimer_t *timer, uint32_t offset)
{
    DEBUG("timer_set(): offset=%" PRIu32 " now=%" PRIu32 " (%" PRIu32 ")\n", offset, xtimer_now(), _xtimer_now());
    if (!timer->callback) {
        DEBUG("timer_set(): timer has no callback.\n");
        return;
    }

    xtimer_remove(timer);
    uint32_t target = xtimer_now() + offset;

    if (offset < XTIMER_BACKOFF) {
        xtimer_spin(offset);
        _shoot(timer);
    }
    else {
        _xtimer_set_absolute(timer, target);
    }
}
Exemplo n.º 14
0
static int nvram_spi_write_9bit_addr(nvram_t *dev, uint8_t *src, uint32_t dst, size_t len)
{
    nvram_spi_params_t *spi_dev = (nvram_spi_params_t *) dev->extra;
    int status;
    uint8_t cmd;
    uint8_t addr;
    cmd = NVRAM_SPI_CMD_WRITE;
    /* The upper address bit is mixed into the command byte on certain devices,
     * probably just to save a byte in the SPI transfer protocol. */
    if (dst > 0xff) {
        cmd |= 0x08;
    }
    /* LSB of address */
    addr = (dst & 0xff);
    spi_acquire(spi_dev->spi);
    gpio_clear(spi_dev->cs);
    /* Enable writes */
    status = spi_transfer_byte(spi_dev->spi, NVRAM_SPI_CMD_WREN, NULL);
    if (status < 0)
    {
        return status;
    }
    gpio_set(spi_dev->cs);
    xtimer_spin(NVRAM_SPI_CS_TOGGLE_TICKS);
    gpio_clear(spi_dev->cs);
    /* Write command and address */
    status = spi_transfer_reg(spi_dev->spi, cmd, addr, NULL);
    if (status < 0)
    {
        return status;
    }
    /* Keep holding CS and write data */
    status = spi_transfer_bytes(spi_dev->spi, (char *)src, NULL, len);
    if (status < 0)
    {
        return status;
    }
    gpio_set(spi_dev->cs);
    spi_release(spi_dev->spi);
    /* status contains the number of bytes actually written to the SPI bus. */
    return status;
}
Exemplo n.º 15
0
int nrf24l01p_init(nrf24l01p_t *dev, spi_t spi, gpio_t ce, gpio_t cs, gpio_t irq)
{
    int status;
    static const char INITIAL_TX_ADDRESS[] =  {0xe7, 0xe7, 0xe7, 0xe7, 0xe7,};
    static const char INITIAL_RX_ADDRESS[] =  {0xe7, 0xe7, 0xe7, 0xe7, 0xe7,};

    dev->spi = spi;
    dev->ce = ce;
    dev->cs = cs;
    dev->irq = irq;
    dev->listener = KERNEL_PID_UNDEF;

    /* Init CE pin */
    gpio_init(dev->ce, GPIO_OUT);

    /* Init CS pin */
    spi_init_cs(dev->spi, dev->cs);

    /* Init IRQ pin */
    gpio_init_int(dev->irq, GPIO_IN_PU, GPIO_FALLING, nrf24l01p_rx_cb, dev);

    /* Test the SPI connection */
    if (spi_acquire(dev->spi, dev->cs, SPI_MODE, SPI_CLK) != SPI_OK) {
        DEBUG("error: unable to acquire SPI bus with given params\n");
        return -1;
    }
    spi_release(dev->spi);

    xtimer_spin(DELAY_AFTER_FUNC_TICKS);

    /* Flush TX FIFIO */
    status = nrf24l01p_flush_tx_fifo(dev);

    if (status < 0) {
        return status;
    }

    /* Flush RX FIFIO */
    status = nrf24l01p_flush_rx_fifo(dev);

    if (status < 0) {
        return status;
    }

    /* Setup adress width */
    status = nrf24l01p_set_address_width(dev, NRF24L01P_AW_5BYTE);

    if (status < 0) {
        return status;
    }

    /* Setup payload width */
    status = nrf24l01p_set_payload_width(dev, NRF24L01P_PIPE0, NRF24L01P_MAX_DATA_LENGTH);

    if (status < 0) {
        return status;
    }

    /* Set RF channel */
    status = nrf24l01p_set_channel(dev, INITIAL_RF_CHANNEL);

    if (status < 0) {
        return status;
    }

    /* Set RF power */
    status = nrf24l01p_set_power(dev, INITIAL_RX_POWER_0dB);

    if (status < 0) {
        return status;
    }

    /* Set RF datarate */
    status = nrf24l01p_set_datarate(dev, NRF24L01P_DR_250KBS);

    if (status < 0) {
        return status;
    }

    /* Set TX Address */
    status = nrf24l01p_set_tx_address(dev, INITIAL_TX_ADDRESS, INITIAL_ADDRESS_WIDTH);

    if (status < 0) {
        return status;
    }

    /* Set RX Adress */
    status = nrf24l01p_set_rx_address(dev, NRF24L01P_PIPE0, INITIAL_RX_ADDRESS, INITIAL_ADDRESS_WIDTH);

    if (status < 0) {
        return status;
    }

    /* Reset auto ack for all pipes */
    status = nrf24l01p_disable_all_auto_ack(dev);

    if (status < 0) {
        return status;
    }

    /* Setup Auto ACK and retransmission */
    status = nrf24l01p_setup_auto_ack(dev, NRF24L01P_PIPE0, NRF24L01P_RETR_750US, 15);

    if (status < 0) {
        return status;
    }

    /* Setup CRC */
    status = nrf24l01p_enable_crc(dev, NRF24L01P_CRC_2BYTE);

    if (status < 0) {
        return status;
    }

    /* Reset all interrupt flags */
    status = nrf24l01p_reset_all_interrupts(dev);

    if (status < 0) {
        return status;
    }

    return nrf24l01p_on(dev);
}
Exemplo n.º 16
0
int nrf24l01p_init(nrf24l01p_t *dev, spi_t spi, gpio_t ce, gpio_t cs, gpio_t irq)
{
    int status;
    char INITIAL_TX_ADDRESS[] =  {0xe7, 0xe7, 0xe7, 0xe7, 0xe7,};
    char INITIAL_RX_ADDRESS[] =  {0xe7, 0xe7, 0xe7, 0xe7, 0xe7,};

    dev->spi = spi;
    dev->ce = ce;
    dev->cs = cs;
    dev->irq = irq;
    dev->listener = KERNEL_PID_UNDEF;

    /* Init CE pin */
    gpio_init(dev->ce, GPIO_DIR_OUT, GPIO_NOPULL);

    /* Init CS pin */
    gpio_init(dev->cs, GPIO_DIR_OUT, GPIO_NOPULL);
    gpio_set(dev->cs);

    /* Init IRQ pin */
    gpio_init_int(dev->irq, GPIO_PULLUP, GPIO_FALLING, nrf24l01p_rx_cb, dev);


    /* Init SPI */
    spi_poweron(dev->spi);
    spi_acquire(dev->spi);
    status = spi_init_master(dev->spi, SPI_CONF_FIRST_RISING, SPI_SPEED_400KHZ);
    spi_release(dev->spi);

    if (status < 0) {
        return status;
    }

    xtimer_spin(DELAY_AFTER_FUNC_TICKS);

    /* Flush TX FIFIO */
    status = nrf24l01p_flush_tx_fifo(dev);

    if (status < 0) {
        return status;
    }

    /* Flush RX FIFIO */
    status = nrf24l01p_flush_rx_fifo(dev);

    if (status < 0) {
        return status;
    }

    /* Setup adress width */
    status = nrf24l01p_set_address_width(dev, NRF24L01P_AW_5BYTE);

    if (status < 0) {
        return status;
    }

    /* Setup payload width */
    status = nrf24l01p_set_payload_width(dev, NRF24L01P_PIPE0, NRF24L01P_MAX_DATA_LENGTH);

    if (status < 0) {
        return status;
    }

    /* Set RF channel */
    status = nrf24l01p_set_channel(dev, INITIAL_RF_CHANNEL);

    if (status < 0) {
        return status;
    }

    /* Set RF power */
    status = nrf24l01p_set_power(dev, INITIAL_RX_POWER_0dB);

    if (status < 0) {
        return status;
    }

    /* Set RF datarate */
    status = nrf24l01p_set_datarate(dev, NRF24L01P_DR_250KBS);

    if (status < 0) {
        return status;
    }

    /* Set TX Address */
    status = nrf24l01p_set_tx_address(dev, INITIAL_TX_ADDRESS, INITIAL_ADDRESS_WIDTH);

    if (status < 0) {
        return status;
    }

    /* Set RX Adress */
    status = nrf24l01p_set_rx_address(dev, NRF24L01P_PIPE0, INITIAL_RX_ADDRESS, INITIAL_ADDRESS_WIDTH);

    if (status < 0) {
        return status;
    }

    /* Reset auto ack for all pipes */
    status = nrf24l01p_disable_all_auto_ack(dev);

    if (status < 0) {
        return status;
    }

    /* Setup Auto ACK and retransmission */
    status = nrf24l01p_setup_auto_ack(dev, NRF24L01P_PIPE0, NRF24L01P_RETR_750US, 15);

    if (status < 0) {
        return status;
    }

    /* Setup CRC */
    status = nrf24l01p_enable_crc(dev, NRF24L01P_CRC_2BYTE);

    if (status < 0) {
        return status;
    }

    /* Reset all interrupt flags */
    status = nrf24l01p_reset_all_interrupts(dev);

    if (status < 0) {
        return status;
    }

    return nrf24l01p_on(dev);
}
Exemplo n.º 17
0
void nrf24l01p_stop(const nrf24l01p_t *dev)
{
    xtimer_spin(DELAY_CS_TOGGLE_TICKS);
    gpio_clear(dev->ce);
}