summaryrefslogtreecommitdiff
path: root/nrf24l01.h
diff options
context:
space:
mode:
Diffstat (limited to 'nrf24l01.h')
-rw-r--r--nrf24l01.h160
1 files changed, 160 insertions, 0 deletions
diff --git a/nrf24l01.h b/nrf24l01.h
new file mode 100644
index 0000000..95d3f48
--- /dev/null
+++ b/nrf24l01.h
@@ -0,0 +1,160 @@
+#ifndef __NRF24L01__H
+#define __NRF24L01__H
+
+#include <unistd.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#include "spi.h"
+
+#define PORT_NRF24L01 PORTB
+#define DDR_NRF24L01 DDRB
+#define DD_CE DDB1
+#define DD_IRQ DDB0
+
+#define NRF24L01_CMD_R_REGISTER 0x00
+#define NRF24L01_CMD_W_REGISTER 0x20
+#define NRF24L01_CMD_R_RX_PAYLOAD 0x61
+#define NRF24L01_CMD_W_TX_PAYLOAD 0xA0
+#define NRF24L01_CMD_NOP 0xFF
+#define NRF24L01_CMD_FLUSH_TX 0xE1
+
+#define NRF24L01_REG_STATUS 0x07
+#define NRF24L01_REG_STATUS_RX_DR 0x06
+#define NRF24L01_REG_STATUS_TX_DS 0x05
+#define NRF24L01_REG_STATUS_MAX_RT 0x04
+#define NRF24L01_REG_RX_PW_P0 0x11
+#define NRF24L01_REG_EN_AA 0x01
+#define NRF24L01_REG_SETUP_RETR 0x04
+#define NRF24L01_REG_CONFIG 0x00
+#define NRF24L01_REG_CONFIG_EN_CRC 0x3
+#define NRF24L01_REG_CONFIG_PWR_UP 0x1
+#define NRF24L01_REG_CONFIG_PRIM_RX 0x0
+
+#define MAX_PAYLOAD_IN_BYTES 1
+
+static inline void nrf24l01_ce_high()
+{
+ PORT_NRF24L01 |= _BV(DD_CE);
+}
+
+static inline void nrf24l01_ce_low()
+{
+ PORT_NRF24L01 &= ~_BV(DD_CE);
+}
+
+static inline uint8_t nrf24l01_read_cmd(uint8_t cmd)
+{
+ return spi_two_byte(cmd, NRF24L01_CMD_NOP);
+}
+
+static inline uint8_t nrf24l01_read_reg(uint8_t reg)
+{
+ return nrf24l01_read_cmd(NRF24L01_CMD_R_REGISTER | reg);
+}
+
+static inline void nrf24l01_write_cmd(uint8_t cmd, uint8_t data)
+{
+ spi_two_byte(cmd, data);
+}
+
+static inline void nrf24l01_write_reg(uint8_t reg, uint8_t data)
+{
+ nrf24l01_write_cmd(NRF24L01_CMD_W_REGISTER | reg, data);
+}
+
+static inline void nrf24l01_power_up()
+{
+ uint8_t config = nrf24l01_read_reg(NRF24L01_REG_CONFIG);
+ nrf24l01_write_reg(NRF24L01_REG_CONFIG, config | _BV(NRF24L01_REG_CONFIG_PWR_UP));
+ _delay_us(10);
+}
+
+static inline void nrf24l01_power_down()
+{
+ uint8_t config = nrf24l01_read_reg(NRF24L01_REG_CONFIG);
+ nrf24l01_write_reg(NRF24L01_REG_CONFIG, config & ~_BV(NRF24L01_REG_CONFIG_PWR_UP));
+}
+
+static inline void nrf24l01_init()
+{
+ spi_init();
+
+ //nrf24l01_write_reg(NRF24L01_REG_SETUP_RETR, 0x00);
+ //nrf24l01_write_reg(NRF24L01_REG_EN_AA, 0x00);
+ nrf24l01_write_reg(NRF24L01_REG_RX_PW_P0, MAX_PAYLOAD_IN_BYTES);
+ nrf24l01_ce_low();
+}
+
+static inline void nrf24l01_receive_mode()
+{
+ uint8_t config = nrf24l01_read_reg(NRF24L01_REG_CONFIG);
+ nrf24l01_write_reg(NRF24L01_REG_CONFIG, config | _BV(NRF24L01_REG_CONFIG_PRIM_RX));
+ nrf24l01_ce_high();
+ _delay_us(200);
+}
+
+static inline void nrf24l01_transmit_mode()
+{
+ uint8_t config = nrf24l01_read_reg(NRF24L01_REG_CONFIG);
+ config &= ~_BV(NRF24L01_REG_CONFIG_PRIM_RX);
+
+ nrf24l01_ce_low();
+ nrf24l01_write_reg(NRF24L01_REG_CONFIG, config);
+ nrf24l01_ce_high();
+ _delay_us(15);
+ nrf24l01_ce_low();
+ _delay_us(200);
+}
+
+static inline uint8_t is_data_received()
+{
+ uint8_t status = nrf24l01_read_reg(NRF24L01_REG_STATUS);
+ return status & _BV(NRF24L01_REG_STATUS_RX_DR);
+}
+
+static inline uint8_t nrf24l01_receive_byte()
+{
+ return nrf24l01_read_cmd(NRF24L01_CMD_R_RX_PAYLOAD);
+}
+
+static inline uint8_t is_data_transmitted(uint8_t status)
+{
+ return status & _BV(NRF24L01_REG_STATUS_TX_DS);
+}
+
+static inline uint8_t is_data_transmit_failed(uint8_t status)
+{
+ return status & _BV(NRF24L01_REG_STATUS_MAX_RT);
+}
+
+static inline int nrf24l01_send_byte(uint8_t data)
+{
+ nrf24l01_write_cmd(NRF24L01_CMD_W_TX_PAYLOAD, data);
+ nrf24l01_transmit_mode();
+
+ uint8_t status;
+ uint8_t err = 0;
+
+ while (1) {
+ status = nrf24l01_read_reg(NRF24L01_REG_STATUS);
+
+ if(is_data_transmitted(status)) {
+ nrf24l01_write_reg(NRF24L01_REG_STATUS, status);
+ break;
+ }
+
+ if(is_data_transmit_failed(status)) {
+ nrf24l01_write_cmd(NRF24L01_CMD_FLUSH_TX, NRF24L01_CMD_NOP);
+ err = 1;
+ break;
+ }
+
+ _delay_us(10000);
+ }
+
+ nrf24l01_write_reg(NRF24L01_REG_STATUS, status);
+ nrf24l01_receive_mode();
+ return err;
+}
+
+#endif // NRF24L01__H