/*
 * true's NRF24L01+ C library
 * shamelessly stolen and modified heavily from some other shit
 * basically: it's better than nothing
 */


#ifndef __TRUE_NRF24L01_LIB_H
#define __TRUE_NRF24L01_LIB_H


/* common libraries */
#include <stdint.h>
#include "nRF24L01.h"


/* user compile-time configuration */
#define _TRNRF_MAX_PACKET_SIZE 			32 		// 32 is the max the radio can handle
 	 	 	 	 	 	 	 	 	 	 		// set lower to save memory


/* platform driver select */
#include "true_nRF24L01_stm32l1xx.h"


/* compile-time user configuration */
#define _TRNRF_USE_INTERRUPT_PIN 				// enables the use of interrupt pin
												// only interrupt-mode implemented, currently mandatory


/* nrf library constants */
#define _TRNRF_MODE_OFF 				0x00
#define _TRNRF_MODE_STANDBY 			0x01
#define _TRNRF_MODE_RX 					0x10
#define _TRNRF_MODE_TX 					0x20
#define _TRNRF_MODE_MASK 				0x3f

#define _TRNRF_UPDATE_ALL 				0xff
#define _TRNRF_UPDATE_EN_RXADDR 		0x01
#define _TRNRF_UPDATE_EN_AA 			0x02
#define _TRNRF_UPDATE_SETUP_AW 			0x04
#define _TRNRF_UPDATE_SETUP_RETR 		0x08
#define _TRNRF_UPDATE_RF_CH 			0x10
#define _TRNRF_UPDATE_RF_SETUP 			0x20
#define _TRNRF_UPDATE_CRC 				0x40
#define _TRNRF_UPDATE_DYNPD 			0x80 	// this and
#define _TRNRF_UPDATE_FEATURE 			0x80 	// this should be updated together anyway

#define _TRNRF_ACK 						0
#define _TRNRF_NO_ACK 					1

#define _TRNRF_MAX_RT_AUTOFLUSH 		0x80
#define _TRNRF_MAX_RT_NO_FLUSH 			0x00

#define _TRNRF_DYN_PAYLOAD 				0xff


/* config struct */
typedef struct nrfConfig {
	uint8_t channel; 			// 0-125, 2400MHz to 2525MHz
	uint8_t rate_power; 		// data rate, tx power
	uint8_t addr_width; 		// width of address, from 2-5 bytes
	uint8_t payload_size[6]; 	// per-pipe RX payload length, from 1-32 bytes, 0=variable payload
	uint8_t crc; 				// crc enable and crc mode bits
	uint8_t pipe_ena; 			// rx pipe enable bits
	uint8_t autoack_ena; 		// per-pipe autoack (enhanced shockburst) on/off
	uint8_t retry; 				// global autoack retry config
	uint8_t *tx_addr; 			// pointer to tx address, addr_width long
	uint8_t tx_config; 			// state to go into after transmitting a packet, flush max_rt FIFO automatically?
	uint8_t *rx_addr_p0; 		// pointer to rxp0 address, addr_width long
	uint8_t *rx_addr_p1; 		// pointer to rxp1 address, addr_width long
	uint8_t rx_pipe[4]; 		// rxp2-rxp5 last byte of address
} nrfConfig;



/* data handling */
void (*nRF24_rx_cb)(uint8_t pipe, uint8_t *pBuf, uint8_t len);
void (*nRF24_tx_done_cb)();
void (*nRF24_tx_max_rt_cb)();


/* function prototypes */
void    nRF24_init(uint32_t cpu_freq);
uint8_t nRF24_interrupt();

uint8_t nRF24_reg_rw(uint8_t reg, uint8_t value);
uint8_t nRF24_reg_write(uint8_t cmd);
uint8_t nRF24_reg_read(uint8_t reg);
uint8_t nRF24_buf_write(uint8_t reg, void *pBuf, uint8_t bytes);
uint8_t nRF24_buf_read(uint8_t reg, void *pBuf, uint8_t bytes);

uint8_t nRF24_is_present(void);

void    nRF24_set_txaddr(const uint8_t *addr);
void    nRF24_set_rxaddr(uint8_t pipe, const uint8_t *addr);

void    nRF24_set_channel(uint8_t chan);
void    nRF24_set_rate(uint8_t rate);
void    nRF24_set_power(uint8_t power);
void    nRF24_set_addr_width(uint8_t width);
void    nRF24_set_payload_size(uint8_t pipe, uint8_t size);
void    nRF24_set_crc(uint8_t crc);
void    nRF24_set_pipe(uint8_t pipe, uint8_t onoff);
void    nRF24_set_autoack(uint8_t pipe, uint8_t onoff);
void    nRF24_set_dynack(uint8_t onoff);

void    nRF24_update_config(uint8_t mask);

void    nRF24_set_tx_config(uint8_t max_rt_flush, uint8_t new_done_state);

void    nRF24_mode_rx();
void    nRF24_mode_tx();
void    nRF24_mode_standby();
void    nRF24_mode_off();
uint8_t nRF24_mode_get();

uint8_t nRF24_data_is_ready(void);

int8_t  nRF24_packet_rx(uint8_t status, void *pBuf);
void    nRF24_packet_tx(void *pBuf, uint8_t bytes, uint8_t noack);
uint8_t nRF24_rx_received_pipe();

void    nRF24_clear_irq_flags(void);



#endif /* __TRUE_NRF24L01_LIB_H */
