/**************** Preprocessor Constants ***************************************/
#define CONFIG 0x20
#define EN_AA 0x21
#define EN_RXADDR 0x22
#define SETUP_AW 0x23
#define SETUP_RETR 0x24
#define RF_CH 0x25
#define RF_SETUP 0x26
#define STATUS 0x27
#define RX_ADDR_P0 0x2A
#define TX_ADDR 0x30
#define RX_PW_P0 0x31
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define TX_PAYLOAD 0xA0
#define RX_PAYLOAD 0x61
#define NO_OP 0xFF
#define ZERO 0x00
#define EOT 0x04
#define PAYLOAD_SIZE 0x20
#define start_transmit {output_high(rf_CE);delay_ms(10);output_low(rf_CE);} //Pulse NRF24L01 CE pin for 20us
int1 rf_interrupt=false; // Declare interrupt flag default is false
static int16 rf_CE,rf_CSN; // Declare NRF24L01 SPI CE & CSN pins
/**************** Gets The Length Of A Data Packet *****************************/
unsigned int* length(unsigned char *data)
{
int *cnt; // Declare a pointer
for (cnt = data; *cnt != 0; cnt++); // Loop
return(cnt - data); // Return the length of the data
}
/**************** Write To NRF24L01 Configuration Register *********************/
void set_register(unsigned int command,unsigned char data)
{
output_low(rf_CSN); // Engage SPI chip select
delay_us(5);
spi_write(command); // Write to register
if(data!=NO_OP){spi_write(data);} // Write data to register
output_high(rf_CSN); // Dis-engage SPI chip select
delay_us(10);
}
/**************** Write To NRF24L01 Configuration Register *********************/
void set_register(unsigned int command,unsigned char* data)
{
int i,len;
len=length(data); // Get the length of the data
output_low(rf_CSN); // Engage SPI chip select
delay_us(5);
spi_write(command); // Write to register
for(i=0;i<len;i++){spi_write(data[i]);} // Write data to register
output_high(rf_CSN); // Dis-engage SPI chip select
delay_us(10);
}
/**************** Enables NRF24L01 Transmit/Receive Mode ***********************/
void transmit_mode(unsigned int1 enable)
{
output_low(rf_CE); // Disable receiver
set_register(STATUS,0x7E); // Clear all interrupts
if(enable)
{
set_register(FLUSH_TX,NO_OP); // Flush TX FIFO buffer
set_register(CONFIG,0x52); // Power up in transmit mode
}
else
{
set_register(FLUSH_RX,NO_OP); // Flush RX FIFO buffer
set_register(CONFIG,0x33); // Power up in receive mode
output_high(rf_CE); // Enable receiver
delay_us(130); // Delay 130us
}
}
/**************** Transmits A Single Byte **************************************/
void rf_transmit(unsigned char data)
{
transmit_mode(true); // Enable transmit mode
output_low(rf_CSN); // Engage SPI chip select
spi_write(TX_PAYLOAD); // Select tx payload register
spi_write(data); // Write data to tx payload register
spi_write(EOT); // End of transmission
output_high(rf_CSN); // Dis-engage SPI chip select
start_transmit; // Start transmission
transmit_mode(false); // Enable receive mode
delay_ms(50); // Delay 50ms
}
/**************** Transmits A String Of Data ***********************************/
void rf_transmit(unsigned char *string)
{
int i,len=0;
char c;
len=length(string); // Get the length of the data to transmit
transmit_mode(true); // Enable transmit mode
output_low(rf_CSN); // Engage SPI chip select
spi_write(TX_PAYLOAD); // Select tx payload register
for(i=0;i<len;i++){
c=string[i];
spi_write(c);} // Write data to tx payload register
spi_write(EOT); // End of transmission
output_high(rf_CSN); // Dis-engage SPI chip select
start_transmit; // Start transmission
transmit_mode(false); // Enable receive mode
delay_ms(50); // Delay 50ms
}
/**************** Receive RF Data **********************************************/
unsigned char* rf_receive()
{
int i;
static int rf_rx_buffer[PAYLOAD_SIZE]={0}; // Declare a receive buffer
rf_interrupt = false; // Clear interrupt flag
output_low(rf_CE); // Disable receiver
output_low(rf_CSN); // Engage SPI chip select
spi_write(RX_PAYLOAD); // Initialize RX payload register
for(i=0;i<=PAYLOAD_SIZE;i++)
{
rf_rx_buffer[i]=spi_read(RX_PAYLOAD); // Copy data from NRF24L01 to buffer
if(rf_rx_buffer[i]==EOT){rf_rx_buffer[i]=ZERO;break;} // Stop when EOT found
}
output_high(rf_CSN); // Dis-engage SPI chip select
transmit_mode(false); // Enable receive mode
return rf_rx_buffer; // Return received payload
}
/**************** Checks The Status Register ***********************************/
void check_interrupt()
{
int i,reg;
output_low(rf_CSN); // Engage SPI chip select
for(i=0;i<5;i++){reg=spi_read(0x07)&0xFF;} // Read 5 chars of data from NRF24L01 RX register
output_high(rf_CSN); // Dis-engage SPI chip select
if(reg>>6){rf_interrupt = true;} // If RX_DR set,set data ready flag
else{set_register(STATUS,0x7E);} // Clear all interrupts
}
char read_register(unsigned int command)
{
char dato;
output_low(rf_CSN); // Engage SPI chip select
//spi_write(command&0x3F); // Write to register
dato=spi_read(command&0x1F); // Write data to register
dato=spi_read(0xFF); // Write data to register
output_high(rf_CSN); // Dis-engage SPI chip select
delay_us(10);
return(dato);
}
/**************** Initialize NRF24L01 Chip *************************************/
void setup_rf(unsigned int16 CE,unsigned int16 CSN,unsigned int* address,unsigned int CH,unsigned boolean Mbps,unsigned int dBm)
{
rf_CE=CE; // Define CE pin
rf_CSN=CSN; // Define CSN pin
//setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_64); // Setup hardware spi
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_64| SPI_XMIT_L_TO_H | SPI_SAMPLE_AT_END); // Configura la comunicación SPI
output_low(rf_CE); // Disable receiver
set_register(CONFIG,0x31); // Power down chip
set_register(RF_CH,CH); // Set RF channel
set_register(RF_SETUP,(Mbps<<3)|(dBm<<1)|0x01); // Set data rate and power level
//set_register(RF_SETUP,0b00010001);//(Mbps<<3)|(dBm<<1)|0x01); // Set data rate and power level
set_register(SETUP_AW,0x03); // Set address width to 5 bytes
set_register(EN_AA,0x0); //0 // Disable auto acknowledgement
set_register(SETUP_RETR,0x05); // Set auto retransmission for 5 tries
set_register(TX_ADDR,address); // Set transmit address
set_register(RX_ADDR_P0,address); // Set receive address
set_register(EN_RXADDR,0x00); // Enable RX address 0
set_register(RX_PW_P0,PAYLOAD_SIZE); // Set RX payload to receive up to 32 characters
transmit_mode(false); // Enable receive mode
}
void Lee_registros() {
printf (usb_cdc_putc
,"Config %X\n\r",read_register
(CONFIG
)); printf (usb_cdc_putc
,"RF_CH %X\n\r",read_register
(RF_CH
)); printf (usb_cdc_putc
,"RF_SETUP %X\n\r",read_register
(RF_SETUP
)); printf (usb_cdc_putc
,"SETUP_AW %X\n\r",read_register
(SETUP_AW
)); printf (usb_cdc_putc
,"EN_AA %X\n\r",read_register
(EN_AA
)); printf (usb_cdc_putc
,"SETUP_RETR %X\n\r",read_register
(SETUP_RETR
)); printf (usb_cdc_putc
,"TX_ADDR %X\n\r",read_register
(TX_ADDR
)); printf (usb_cdc_putc
,"RX_ADDR_P0 %X\n\r",read_register
(RX_ADDR_P0
)); printf (usb_cdc_putc
,"EN_RXADDR %X\n\r",read_register
(EN_RXADDR
)); printf (usb_cdc_putc
,"RX_PW_P0 %X\n\r",read_register
(RX_PW_P0
));
}