|
|
|
@ -31,43 +31,34 @@
|
|
|
|
|
#define DELAY_AFTER_FUNC_TICKS (xtimer_ticks_from_usec(DELAY_AFTER_FUNC_US)) |
|
|
|
|
#define DELAY_CHANGE_TXRX_TICKS (xtimer_ticks_from_usec(DELAY_CHANGE_TXRX_US)) |
|
|
|
|
|
|
|
|
|
#define SPI_MODE SPI_MODE_0 |
|
|
|
|
#define SPI_CLK SPI_CLK_400KHZ |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
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 (status < 0) ? status : 0; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int nrf24l01p_write_reg(nrf24l01p_t *dev, char reg, char write) |
|
|
|
|
{ |
|
|
|
|
int status; |
|
|
|
|
char reg_content; |
|
|
|
|
|
|
|
|
|
/* 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_W_REGISTER | (REGISTER_MASK & reg)), write, ®_content); |
|
|
|
|
xtimer_spin(DELAY_CS_TOGGLE_TICKS); |
|
|
|
|
gpio_set(dev->cs); |
|
|
|
|
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 (status < 0) ? status : 0; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -87,22 +78,17 @@ int nrf24l01p_init(nrf24l01p_t *dev, spi_t spi, gpio_t ce, gpio_t cs, gpio_t irq
|
|
|
|
|
gpio_init(dev->ce, GPIO_OUT); |
|
|
|
|
|
|
|
|
|
/* Init CS pin */ |
|
|
|
|
gpio_init(dev->cs, GPIO_OUT); |
|
|
|
|
gpio_set(dev->cs); |
|
|
|
|
spi_init_cs(dev->spi, dev->cs); |
|
|
|
|
|
|
|
|
|
/* Init IRQ pin */ |
|
|
|
|
gpio_init_int(dev->irq, GPIO_IN_PU, 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; |
|
|
|
|
/* 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); |
|
|
|
|
|
|
|
|
@ -237,20 +223,14 @@ void nrf24l01p_transmit(nrf24l01p_t *dev)
|
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
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 status; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void nrf24l01p_register(nrf24l01p_t *dev, unsigned int *pid) |
|
|
|
@ -288,23 +268,16 @@ void nrf24l01p_stop(nrf24l01p_t *dev)
|
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
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 status; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -395,27 +368,21 @@ int nrf24l01p_set_payload_width(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pipe, char
|
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
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 (status < 0) ? status : length; |
|
|
|
|
return (int)length; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int nrf24l01p_set_tx_address_long(nrf24l01p_t *dev, uint64_t saddr, unsigned int length) |
|
|
|
|
{ |
|
|
|
|
int status; |
|
|
|
|
|
|
|
|
|
char buf[length]; |
|
|
|
|
|
|
|
|
|
if (length <= INITIAL_ADDRESS_WIDTH) { |
|
|
|
@ -429,44 +396,32 @@ int nrf24l01p_set_tx_address_long(nrf24l01p_t *dev, uint64_t saddr, unsigned int
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 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)), buf, NULL, length); /* address width is 5 byte */ |
|
|
|
|
xtimer_spin(DELAY_CS_TOGGLE_TICKS); |
|
|
|
|
gpio_set(dev->cs); |
|
|
|
|
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)), |
|
|
|
|
buf, NULL, length); |
|
|
|
|
/* Release the bus for other threads. */ |
|
|
|
|
spi_release(dev->spi); |
|
|
|
|
|
|
|
|
|
xtimer_spin(DELAY_AFTER_FUNC_TICKS); |
|
|
|
|
|
|
|
|
|
return (status < 0) ? status : length; |
|
|
|
|
return (int)length; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint64_t nrf24l01p_get_tx_address_long(nrf24l01p_t *dev) |
|
|
|
|
{ |
|
|
|
|
int status; |
|
|
|
|
uint64_t saddr_64 = 0; |
|
|
|
|
char addr_array[INITIAL_ADDRESS_WIDTH]; |
|
|
|
|
|
|
|
|
|
/* 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_REGISTER | (REGISTER_MASK & REG_TX_ADDR)), 0, addr_array, INITIAL_ADDRESS_WIDTH); /* address width is 5 byte */ |
|
|
|
|
xtimer_spin(DELAY_CS_TOGGLE_TICKS); |
|
|
|
|
gpio_set(dev->cs); |
|
|
|
|
spi_acquire(dev->spi, dev->cs, SPI_MODE, SPI_CLK); |
|
|
|
|
spi_transfer_regs(dev->spi, dev->cs, |
|
|
|
|
(CMD_R_REGISTER | (REGISTER_MASK & REG_TX_ADDR)), |
|
|
|
|
NULL, addr_array, INITIAL_ADDRESS_WIDTH); |
|
|
|
|
/* Release the bus for other threads. */ |
|
|
|
|
spi_release(dev->spi); |
|
|
|
|
|
|
|
|
|
xtimer_spin(DELAY_AFTER_FUNC_TICKS); |
|
|
|
|
|
|
|
|
|
if (status < 0) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
xtimer_spin(DELAY_AFTER_FUNC_TICKS); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < INITIAL_ADDRESS_WIDTH; i++) { |
|
|
|
|
saddr_64 |= (((uint64_t) addr_array[i]) << (8 * (INITIAL_ADDRESS_WIDTH - i - 1))); |
|
|
|
|
} |
|
|
|
@ -477,7 +432,6 @@ uint64_t nrf24l01p_get_tx_address_long(nrf24l01p_t *dev)
|
|
|
|
|
|
|
|
|
|
int nrf24l01p_set_rx_address(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pipe, char *saddr, unsigned int length) |
|
|
|
|
{ |
|
|
|
|
int status; |
|
|
|
|
char pipe_addr; |
|
|
|
|
|
|
|
|
|
switch (pipe) { |
|
|
|
@ -510,12 +464,10 @@ int nrf24l01p_set_rx_address(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pipe, char *s
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 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 & pipe_addr)), saddr, NULL, length); /* address width is 5 byte */ |
|
|
|
|
xtimer_spin(DELAY_CS_TOGGLE_TICKS); |
|
|
|
|
gpio_set(dev->cs); |
|
|
|
|
spi_acquire(dev->spi, dev->cs, SPI_MODE, SPI_CLK); |
|
|
|
|
spi_transfer_regs(dev->spi, dev->cs, |
|
|
|
|
(CMD_W_REGISTER | (REGISTER_MASK & pipe_addr)), |
|
|
|
|
saddr, NULL, length); |
|
|
|
|
/* Release the bus for other threads. */ |
|
|
|
|
spi_release(dev->spi); |
|
|
|
|
|
|
|
|
@ -523,7 +475,7 @@ int nrf24l01p_set_rx_address(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pipe, char *s
|
|
|
|
|
|
|
|
|
|
/* Enable this pipe */ |
|
|
|
|
nrf24l01p_enable_pipe(dev, pipe); |
|
|
|
|
return (status < 0) ? status : length; |
|
|
|
|
return (int)length; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int nrf24l01p_set_rx_address_long(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pipe, uint64_t saddr, unsigned int length) |
|
|
|
@ -546,7 +498,6 @@ int nrf24l01p_set_rx_address_long(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pipe, ui
|
|
|
|
|
|
|
|
|
|
uint64_t nrf24l01p_get_rx_address_long(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pipe) |
|
|
|
|
{ |
|
|
|
|
int status; |
|
|
|
|
char pipe_addr; |
|
|
|
|
uint64_t saddr_64 = 0; |
|
|
|
|
|
|
|
|
@ -582,19 +533,13 @@ uint64_t nrf24l01p_get_rx_address_long(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pip
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 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_REGISTER | (REGISTER_MASK & pipe_addr)), 0, addr_array, INITIAL_ADDRESS_WIDTH); /* address width is 5 byte */ |
|
|
|
|
xtimer_spin(DELAY_CS_TOGGLE_TICKS); |
|
|
|
|
gpio_set(dev->cs); |
|
|
|
|
spi_acquire(dev->spi, dev->cs, SPI_MODE, SPI_CLK); |
|
|
|
|
spi_transfer_regs(dev->spi, dev->cs, |
|
|
|
|
(CMD_R_REGISTER | (REGISTER_MASK & pipe_addr)), |
|
|
|
|
NULL, addr_array, INITIAL_ADDRESS_WIDTH); |
|
|
|
|
/* Release the bus for other threads. */ |
|
|
|
|
spi_release(dev->spi); |
|
|
|
|
|
|
|
|
|
if (status < 0) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
xtimer_spin(DELAY_AFTER_FUNC_TICKS); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < INITIAL_ADDRESS_WIDTH; i++) { |
|
|
|
@ -635,14 +580,11 @@ int nrf24l01p_set_datarate(nrf24l01p_t *dev, nrf24l01p_dr_t dr)
|
|
|
|
|
|
|
|
|
|
int nrf24l01p_get_status(nrf24l01p_t *dev) |
|
|
|
|
{ |
|
|
|
|
char status; |
|
|
|
|
uint8_t status; |
|
|
|
|
|
|
|
|
|
/* Acquire exclusive access to the bus. */ |
|
|
|
|
spi_acquire(dev->spi); |
|
|
|
|
gpio_clear(dev->cs); |
|
|
|
|
xtimer_spin(DELAY_CS_TOGGLE_TICKS); |
|
|
|
|
spi_transfer_byte(dev->spi, CMD_NOP, &status); |
|
|
|
|
xtimer_spin(DELAY_CS_TOGGLE_TICKS); |
|
|
|
|
gpio_set(dev->cs); |
|
|
|
|
spi_acquire(dev->spi, dev->cs, SPI_MODE, SPI_CLK); |
|
|
|
|
status = spi_transfer_byte(dev->spi, dev->cs, false, CMD_NOP); |
|
|
|
|
/* Release the bus for other threads. */ |
|
|
|
|
spi_release(dev->spi); |
|
|
|
|
|
|
|
|
@ -971,42 +913,28 @@ int nrf24l01p_disable_all_auto_ack(nrf24l01p_t *dev)
|
|
|
|
|
|
|
|
|
|
int nrf24l01p_flush_tx_fifo(nrf24l01p_t *dev) |
|
|
|
|
{ |
|
|
|
|
int status; |
|
|
|
|
char reg_content; |
|
|
|
|
|
|
|
|
|
/* Acquire exclusive access to the bus. */ |
|
|
|
|
spi_acquire(dev->spi); |
|
|
|
|
gpio_clear(dev->cs); |
|
|
|
|
xtimer_spin(DELAY_CS_TOGGLE_TICKS); |
|
|
|
|
status = spi_transfer_byte(dev->spi, CMD_FLUSH_TX, ®_content); |
|
|
|
|
xtimer_spin(DELAY_CS_TOGGLE_TICKS); |
|
|
|
|
gpio_set(dev->cs); |
|
|
|
|
spi_acquire(dev->spi, dev->cs, SPI_MODE, SPI_CLK); |
|
|
|
|
spi_transfer_byte(dev->spi, dev->cs, false, CMD_FLUSH_TX); |
|
|
|
|
/* Release the bus for other threads. */ |
|
|
|
|
spi_release(dev->spi); |
|
|
|
|
|
|
|
|
|
xtimer_spin(DELAY_AFTER_FUNC_TICKS); |
|
|
|
|
|
|
|
|
|
return (status < 0) ? status : 0; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int nrf24l01p_flush_rx_fifo(nrf24l01p_t *dev) |
|
|
|
|
{ |
|
|
|
|
int status; |
|
|
|
|
char reg_content; |
|
|
|
|
|
|
|
|
|
/* Acquire exclusive access to the bus. */ |
|
|
|
|
spi_acquire(dev->spi); |
|
|
|
|
gpio_clear(dev->cs); |
|
|
|
|
xtimer_spin(DELAY_CS_TOGGLE_TICKS); |
|
|
|
|
status = spi_transfer_byte(dev->spi, CMD_FLUSH_RX, ®_content); |
|
|
|
|
xtimer_spin(DELAY_CS_TOGGLE_TICKS); |
|
|
|
|
gpio_set(dev->cs); |
|
|
|
|
spi_acquire(dev->spi, dev->cs, SPI_MODE, SPI_CLK); |
|
|
|
|
spi_transfer_byte(dev->spi, dev->cs, false, CMD_FLUSH_RX); |
|
|
|
|
/* Release the bus for other threads. */ |
|
|
|
|
spi_release(dev->spi); |
|
|
|
|
|
|
|
|
|
xtimer_spin(DELAY_AFTER_FUNC_TICKS); |
|
|
|
|
|
|
|
|
|
return (status < 0) ? status : 0; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void nrf24l01p_rx_cb(void *arg) |
|
|
|
|