Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define F_CPU 8000000UL // 8 MHz
- /* 9600 baud */
- #define UART_BAUD_RATE 9600
- #define DataLen 5 // length of data packet sent / received
- #include <avr/io.h>
- #include <stdio.h>
- #include <util/delay.h>
- #include <avr/interrupt.h>
- #include "uart.h"
- #include "nRF24L01.h"
- #include "lcd.h"
- uint8_t *data;
- /***************** SPI *****************************/ // Sending data between the chip and the chip nrf'ens
- // Initialization
- void InitSPI ( void )
- {
- // Set SCK (PB5), MOSI (PB3), CSN (SS & PB2) & C as outport
- // NOTE! Must be set before the SPI Enable neadn
- DDRB |= (1<<DDB5 ) | ( 1 << DDB3 ) | ( 1 << DDB2 ) | ( 1 << DDB1 );
- /* Enable SPI, Master, set clock rate fck/16 .. can change the speed but it does so much */
- SPCR |= ( 1 << SPE ) | ( 1 << MSTR );// | (1 << SPR0) | (1 << SPR1);
- SETBIT(PORTB,2); // CSN IR_High to start with, we will not send anything to nrf'en yet!
- CLEARBIT(PORTB,1); // CE low to start with, nrf'en will not send / receive anything yet!
- }
- // Send command to nrf'en on then get back a byte
- char WriteByteSPI ( unsigned char CDATA )
- {
- // Load Byte to Data register
- SPDR = CDATA ;
- /* Wait for transmission complete */
- while (!(SPSR & (1<<SPIF)));
- // Return what was sent back by nrf'en (first time after csn-low will Statusregistert)
- return SPDR ;
- }
- void ioinit(){
- }
- // When data is received / sent as goes interr uptet INT0 second-bottom running
- void INT0_interrupt_init ( void )
- {
- DDRD &= ~(1 << DDD2); // Clear the PD2 pin
- // PD2 (INT0 pin) is now an input
- ////PORTD |= (1 << PORTD2); // turn On the Pull-up
- // PD0 is now an input with pull-up enabled
- MCUCR |=(1<<ISC01); // INT0 falling edge PD2
- MCUCR &=~(1<<ISC00); // INT0 falling edge PD2
- GICR |=(1<<INT0); // enablar int0
- sei (); // Enable global interrupts are then
- }
- uint8_t *WriteToNrf(uint8_t ReadWrite,uint8_t reg,uint8_t *val,uint8_t antVal) // takes in "ReadWrite" (W el R), "reg" (a record), "* Choice" (an array) & "antVal" (number integer in the variable)
- {
- //"ReadWrite" ("W" or "R"), "reg" (the register), "*val" (an array with the package) & "antVal" (number of integers in the package)
- ////cei();
- if(ReadWrite == W) // W = want to write to nrf-one (R = read of it, R_REGISTER (0x00), so do not care one else function)
- {
- reg=W_REGISTER + reg; // example: reg = EN_AA: 0b0010 0000 + 0001 = 0b0000 0b0010 0001
- }
- // Static uint8_t for it to go to return an array (note the "*" on the top tool!)
- static uint8_t ret[32]; // assume that the longest you want to read when they call the "R" is dataleng-far, that uses only 1 byte datalengd the want to read out 5bytes RF_Adress so write 5 here ist!
- _delay_us(10); // all the delay is such that the NRF will manage! (Micro seconds)
- CLEARBIT(PORTB,2); // CSN low = nrf chip starts listening
- _delay_us(10);
- WriteByteSPI(reg); // first SPI command after CSN was telling nrf'en which of its records to be edited as: 0b0010 0001 write to registry EN_AA
- _delay_us(10);
- int i;
- for (i=0;i<antVal;i++)
- {
- if (ReadWrite == R && reg!= W_TX_PAYLOAD)
- {
- ret[i]=WriteByteSPI(NOP); // other and the rest of the SPI command tells the NRF which values ??in this case should be read
- _delay_us(10);
- }
- else
- {
- WriteByteSPI(val[i]); // other and the rest of the SPI command tells the NRF which values ??in this case should be written to
- _delay_us(10);
- }
- }
- SETBIT(PORTB,2); // CSN IR_High = nrf chip stop listening
- ////sei(); // enable global interrupt
- return ret; // returns an array
- }
- // Resets nrf'en for new communication
- void reset(void)
- {
- _delay_us(10);
- CLEARBIT(PORTB,2); // CSN Low
- _delay_us(10);
- WriteByteSPI(W_REGISTER + STATUS); //
- _delay_us(10);
- WriteByteSPI(0x70); // conditioned pulls all interrupts in the status register (to be able to listen again)
- _delay_us(10);
- SETBIT(PORTB,2); // CSN IR_High
- }
- //Function to retrieve some thing of nrf's records
- uint8_t GetReg(uint8_t reg)
- {
- // Internal uses: USART_Transmit (GetReg (STATUS)); // Where the status of the registry to Check
- _delay_us(10);
- CLEARBIT (PORTB,2); // CSN Low
- _delay_us(10);
- WriteByteSPI(R_REGISTER+reg); // Which registry would you like to read (now with R_Register because nothing will be written to register)
- _delay_us(10);
- reg=WriteByteSPI(NOP); // Send NOP number of bytes you want to download (usually 1gång, but eg addr is 5 bytes!) and save isf not in the "reg", but an array using a loop
- _delay_us(10);
- SETBIT(PORTB,2); // CSN IR_High
- return reg; // Returns the registry hopefully with bit5 = 1 (tx_ds = successful transmission)
- }
- // Initialize nrf'en (note the NRF must vala to sleep when this happens CE low)
- void nrf24L01_init(void)
- {
- _delay_ms(100); // allow the radio to reach power-down if the shutdown
- uint8_t val[5]; // an array of integers that sends values ??to WriteToNrf function
- //EN_AA - (enable auto-acknowledgments) - Transmitter gets automatic response from receiver when successful transmission! (lovely function!)
- //Only works if Transmitter has identical RF_Adress on its channel ex: RX_ADDR_Po = TX_ADDR
- val[0]=0x01; //set value
- WriteToNrf(W, EN_AA, val, 1); //N=write mode, EN_AA=register to write to, val=data to write, 1=number of data bytes.
- //Choose number of enabled data pipes (1-5)
- val[0]=0x01;
- WriteToNrf(W, EN_RXADDR, val, 1); //enable data pipe 0
- //RF_Adress width setup (how many bytes is the receiver address, the more the merrier 1-5)
- val[0]=0x03; //0b0000 00011 = 5 bytes RF_Adress
- WriteToNrf(W, SETUP_AW, val, 1);
- // RF channel setup - select the frequency from 2.400 to 2.527 GHz 1MHz/steg
- val[0] = 0x01 ;
- WriteToNrf(W,RF_CH,val,1); // RF channel registry 0b0000 0001 = 2.401 GHz (same on the TX RX)
- //RF setup - choose power mode and data speed. Here is the diference with the (+) version!!!
- val[0]=0x27; //00000111 bit 3="0" 1Mbps=longer range, bit 2-1 power mode ("11" = -odB ; "00"=-18dB)
- WriteToNrf(W, RF_SETUP, val, 1);
- //RF_Adress setup 5 byte - Set Receiver address (set RX_ADDR_Po = TX_ADDR if EN_AA is enabled!!!)
- int i=0;
- for(i=0; i<5; i++){
- val[i]=0x11; //ox12 x 5 to get a long and secure address.
- }
- //-------WriteToNrf(W, RX_ADDR_P0, val, 5); //since we chose pipe 0 on EN_RXADDR we give this address to that channel.
- //Here you can give different addresses to different channels (if they are enabled in EN_RXADDR) to listen on several different transmitters)
- //TX RF_Adress setup 5 byte - Set Transmitter address (not used in a receiver but can be set anyway)
- for(i=0; i<5; i++){
- val[i]=0x11; //ox12 x 5 - same on the Receiver chip and the RX-RF_Address above if EN_AA is enabled!!!
- }
- //-------WriteToNrf(W, TX_ADDR, val, 5);
- //Payload width Setup - 1-32byte (how many bytes to send per transmission)
- val[0]=0x05; //Send 5 bytes per package this time (same on receiver and transmitter)
- WriteToNrf(W,RX_PW_P0,val,1);
- val[0]=0x2F; //0b00l0 00011 "2" sets it up to 7SouS delay between every retry (at least Seeus at 25okbps and if payload >5bytes in 1Hbps,
- //and if payload >1Sbyte in 2Hbps) "F" is number of retries (1-15, now 15)
- WriteToNrf(W, SETUP_RETR, val, 1);
- //CONFIG reg setup - Now it's time to boot up the Qgf and choose if it's suppose to be a transmitter or receiver
- val[0]=0x1E; //0b0001 1110 - bit 0="0":transmitter bit 0="1":Receiver, bit 1="1"=power up,
- //bit 4="1"= mask_Max_RT i.e. IRQ-interrupt is not triggered if transmission failed.
- WriteToNrf(W, CONFIG, val, 1);
- //device need 1.5ms to reach standby mode (CE=low)
- _delay_ms(100);
- // Sei ();
- }
- // The receiver opens and "Listening" in 1s
- void receive_payload ( void )
- {
- //sei(); // Enable global interrupt
- SETBIT(PORTB,1); // CE IR_High = "Listening"
- _delay_ms(1000); // listening in 1s and received goes int0-interruptvektor Started
- CLEARBIT(PORTB,1); // ce low back-stop listening
- //cli(); // Disable the global interrupt
- }
- // Send the data
- void transmit_payload( uint8_t *W_buff)
- {
- WriteToNrf(R,FLUSH_TX,W_buff,0); // send 0xE1 which flushes the registry to old data should not be on the wait to be sent when you want to send the new data! R stands for W_REGISTER not be added. sends no command efterråt because it is not needed! W_buff [] is just there to an array has to be there ...
- WriteToNrf(R,W_TX_PAYLOAD,W_buff,DataLen); // send data in W_buff to nrf-one (note can not be read w_tx_payload registry!)
- //sei(); // enable global interrupt already!
- // USART_Transmit (GetReg (STATUS));
- _delay_ms(10); // need to be really ms, not us?? YEEES! otherwise it will not work!
- SETBIT(PORTB,1); // CE high = send data INT0 interruptet running when the transmission was successful and if EN_AA is on, also the response of the receiver is received
- _delay_us ( 20 ); // at least 10us!
- CLEARBIT(PORTB,1); // CE low
- _delay_ms(10); // need to be really ms, not us?? YEEES! otherwise it will not work!
- // Cli (); // Disable the global interrupt ... ajabaja, then closes USART_RX-listening to!
- }
- int main(void)
- {
- lcd_init(LCD_DISP_ON);
- lcd_puts("LCD init");
- _delay_ms(500);
- lcd_clrscr();
- InitSPI();
- lcd_puts("SPI init");
- _delay_ms(500);
- lcd_clrscr();
- ioinit();
- INT0_interrupt_init();
- lcd_puts("INT0 init");
- _delay_ms(500);
- lcd_clrscr();
- nrf24L01_init();
- lcd_puts("NRF init");
- _delay_ms(500);
- lcd_clrscr();
- ////uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
- ////lcd_puts("USART init");
- ////_delay_ms(500);
- ////lcd_clrscr();
- //sei();
- //Clear the screen
- lcd_clrscr();
- char buffer[5];
- lcd_puts("STATUS:");
- itoa( GetReg(STATUS), buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- lcd_puts("TEST:");
- itoa(0xBC, buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- lcd_puts("EA_AA:");
- itoa( GetReg(EN_AA), buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- lcd_puts("EN_RXADDR:");
- itoa( GetReg(EN_RXADDR), buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- lcd_puts("SETUP_AW:");
- itoa( GetReg(SETUP_AW), buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- lcd_puts("RF_CH:");
- itoa( GetReg(RF_CH), buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- lcd_puts("RF_SETUP:");
- itoa( GetReg(RF_SETUP), buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- lcd_puts("RX_ADDR_P0:");
- itoa( GetReg(RX_ADDR_P0), buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- lcd_puts("TX_ADDR:");
- itoa( GetReg(TX_ADDR), buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- lcd_puts("RX_PW_P0:");
- itoa( GetReg(RX_PW_P0), buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- lcd_puts("SETUP_RETR:");
- itoa( GetReg(SETUP_RETR), buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- lcd_puts("CONFIG:");
- itoa( GetReg(CONFIG), buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- while(1){
- reset();
- int i;
- for (i=0;i<5;i++)
- {
- buffer[i]=0x93;
- }
- transmit_payload(buffer);
- lcd_puts("STATUS:");
- itoa( GetReg(STATUS), buffer, 16); // convert interger into string (decimal format)
- lcd_puts(buffer); // and transmit string to UART
- _delay_ms(500);
- lcd_clrscr();
- }
- return 0;
- }
- ISR(INT0_vect) // vector that is triggered when transmit_payload managed to send or when receive_payload received data NOTE: when Mask_Max_rt is set in the config register so it will not go off when MAX_RT is was reached on the mailing lodge nmisslyckats!
- {
- cli(); // Disable the global interrupt
- CLEARBIT(PORTB ,1); // ce low back-stop listening / transmitting
- SETBIT(PORTB,0); // part one
- _delay_ms(500);
- CLEARBIT(PORTB,0); // led off
- // Receiver function to print out on usart:
- data = WriteToNrf (R, R_RX_PAYLOAD, data, DataLen); // Read the received data
- reset();
- for (int i = 0; i <DataLen; i++)
- {
- lcd_putc(data[i]);
- }
- _delay_ms(1000);
- lcd_clrscr();
- sei();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement