#ifndef __NRF24L01__H #define __NRF24L01__H #include #include #include #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