Advertisement
Guest User

NRF Transmitter

a guest
Apr 19th, 2014
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.98 KB | None | 0 0
  1. #define F_CPU 8000000UL   // 8 MHz
  2.  
  3. /* 9600 baud */
  4. #define UART_BAUD_RATE  9600
  5.  
  6. #define DataLen 5   // length of data packet sent / received
  7.  
  8. #include <avr/io.h>
  9. #include <stdio.h>
  10. #include <util/delay.h>
  11. #include <avr/interrupt.h>
  12.  
  13. #include "uart.h"
  14. #include "nRF24L01.h"
  15. #include "lcd.h"
  16.  
  17. uint8_t *data;
  18.  
  19. /***************** SPI *****************************/   // Sending data between the chip and the chip nrf'ens
  20. // Initialization
  21. void  InitSPI ( void )
  22. {
  23.     // Set SCK (PB5), MOSI (PB3), CSN (SS & PB2) & C as outport
  24.     // NOTE! Must be set before the SPI Enable neadn
  25.     DDRB |= (1<<DDB5 ) | ( 1 << DDB3 ) | ( 1 << DDB2 ) | ( 1 << DDB1 );
  26.    
  27.     /* Enable SPI, Master, set clock rate fck/16 .. can change the speed but it does so much */
  28.     SPCR |= ( 1 << SPE ) | ( 1 << MSTR );//  | (1 << SPR0) | (1 << SPR1);
  29.    
  30.     SETBIT(PORTB,2);    // CSN IR_High to start with, we will not send anything to nrf'en yet!
  31.     CLEARBIT(PORTB,1);  // CE low to start with, nrf'en will not send / receive anything yet!
  32. }
  33.  
  34. // Send command to nrf'en on then get back a byte
  35. char  WriteByteSPI ( unsigned  char  CDATA )
  36. {
  37.     // Load Byte to Data register
  38.     SPDR  =  CDATA ;
  39.    
  40.     /* Wait for transmission complete */
  41.     while (!(SPSR & (1<<SPIF)));
  42.    
  43.     // Return what was sent back by nrf'en (first time after csn-low will Statusregistert)
  44.     return SPDR ;
  45. }
  46.  
  47. void ioinit(){
  48.    
  49. }
  50.  
  51. // When data is received / sent as goes interr uptet INT0 second-bottom running
  52. void  INT0_interrupt_init ( void )
  53. {
  54.     DDRD &= ~(1 << DDD2);     // Clear the PD2 pin
  55.     // PD2 (INT0 pin) is now an input
  56.  
  57.     ////PORTD |= (1 << PORTD2);    // turn On the Pull-up
  58.     // PD0 is now an input with pull-up enabled
  59.    
  60.     MCUCR |=(1<<ISC01); // INT0 falling edge PD2
  61.     MCUCR &=~(1<<ISC00); // INT0 falling edge PD2
  62.    
  63.     GICR |=(1<<INT0);   // enablar int0
  64.     sei (); // Enable global interrupts are then
  65. }
  66.  
  67. 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)
  68. {
  69.     //"ReadWrite" ("W" or "R"), "reg" (the register), "*val" (an array with the package) & "antVal" (number of integers in the package)
  70.     ////cei();
  71.    
  72.     if(ReadWrite == W)  // W = want to write to nrf-one (R = read of it, R_REGISTER (0x00), so do not care one else function)
  73.     {
  74.         reg=W_REGISTER + reg;   // example: reg = EN_AA: 0b0010 0000 + 0001 = 0b0000 0b0010 0001
  75.     }
  76.    
  77.     // Static uint8_t for it to go to return an array (note the "*" on the top tool!)
  78.     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!
  79.    
  80.     _delay_us(10);      // all the delay is such that the NRF will manage! (Micro seconds)
  81.     CLEARBIT(PORTB,2);  // CSN low = nrf chip starts listening
  82.     _delay_us(10);
  83.     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
  84.     _delay_us(10);
  85.    
  86.     int  i;
  87.     for (i=0;i<antVal;i++)
  88.     {
  89.         if  (ReadWrite == R && reg!= W_TX_PAYLOAD)
  90.         {
  91.             ret[i]=WriteByteSPI(NOP);   // other and the rest of the SPI command tells the NRF which values ??in this case should be read
  92.             _delay_us(10);
  93.         }
  94.         else
  95.         {
  96.             WriteByteSPI(val[i]);   // other and the rest of the SPI command tells the NRF which values ??in this case should be written to
  97.             _delay_us(10);
  98.         }
  99.     }
  100.     SETBIT(PORTB,2);    // CSN IR_High = nrf chip stop listening
  101.    
  102.     ////sei();  // enable global interrupt
  103.    
  104.     return ret;     // returns an array
  105. }
  106.  
  107. // Resets nrf'en for new communication
  108. void reset(void)
  109. {
  110.     _delay_us(10);
  111.     CLEARBIT(PORTB,2);  // CSN Low
  112.     _delay_us(10);
  113.     WriteByteSPI(W_REGISTER + STATUS);  //
  114.     _delay_us(10);
  115.     WriteByteSPI(0x70);     // conditioned pulls all interrupts in the status register (to be able to listen again)
  116.     _delay_us(10);
  117.     SETBIT(PORTB,2);    // CSN IR_High
  118. }
  119.  
  120. //Function to retrieve some thing of nrf's records
  121. uint8_t GetReg(uint8_t reg)
  122. {
  123.     // Internal uses: USART_Transmit (GetReg (STATUS)); // Where the status of the registry to Check
  124.     _delay_us(10);
  125.     CLEARBIT (PORTB,2);     // CSN Low
  126.     _delay_us(10);
  127.     WriteByteSPI(R_REGISTER+reg);   // Which registry would you like to read (now with R_Register because nothing will be written to register)
  128.     _delay_us(10);
  129.     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
  130.     _delay_us(10);
  131.     SETBIT(PORTB,2);    // CSN IR_High
  132.     return  reg;    // Returns the registry hopefully with bit5 = 1 (tx_ds = successful transmission)
  133. }
  134.  
  135. // Initialize nrf'en (note the NRF must vala to sleep when this happens CE low)
  136. void nrf24L01_init(void)
  137. {
  138.     _delay_ms(100);     // allow the radio to reach power-down if the shutdown
  139.     uint8_t val[5];     // an array of integers that sends values ??to WriteToNrf function
  140.    
  141.     //EN_AA - (enable auto-acknowledgments) - Transmitter gets automatic response from receiver when successful transmission! (lovely function!)
  142.     //Only works if Transmitter has identical RF_Adress on its channel ex: RX_ADDR_Po = TX_ADDR
  143.     val[0]=0x01; //set value
  144.     WriteToNrf(W, EN_AA, val, 1); //N=write mode, EN_AA=register to write to, val=data to write, 1=number of data bytes.
  145.    
  146.     //Choose number of enabled data pipes (1-5)
  147.     val[0]=0x01;
  148.     WriteToNrf(W, EN_RXADDR, val, 1); //enable data pipe 0
  149.  
  150.     //RF_Adress width setup (how many bytes is the receiver address, the more the merrier 1-5)
  151.     val[0]=0x03; //0b0000 00011 = 5 bytes RF_Adress
  152.     WriteToNrf(W, SETUP_AW, val, 1);
  153.  
  154.     // RF channel setup - select the frequency from 2.400 to 2.527 GHz 1MHz/steg
  155.     val[0] = 0x01 ;
  156.     WriteToNrf(W,RF_CH,val,1);  // RF channel registry 0b0000 0001 = 2.401 GHz (same on the TX RX)
  157.  
  158.     //RF setup - choose power mode and data speed. Here is the diference with the (+) version!!!
  159.     val[0]=0x27; //00000111 bit 3="0" 1Mbps=longer range, bit 2-1 power mode ("11" = -odB ; "00"=-18dB)
  160.     WriteToNrf(W, RF_SETUP, val, 1);
  161.  
  162.     //RF_Adress setup 5 byte - Set Receiver address (set RX_ADDR_Po = TX_ADDR if EN_AA is enabled!!!)
  163.     int i=0;
  164.     for(i=0; i<5; i++){
  165.         val[i]=0x11; //ox12 x 5 to get a long and secure address.
  166.     }
  167.     //-------WriteToNrf(W, RX_ADDR_P0, val, 5); //since we chose pipe 0 on EN_RXADDR we give this address to that channel.
  168.     //Here you can give different addresses to different channels (if they are enabled in EN_RXADDR) to listen on several different transmitters)
  169.    
  170.     //TX RF_Adress setup 5 byte - Set Transmitter address (not used in a receiver but can be set anyway)
  171.     for(i=0; i<5; i++){
  172.         val[i]=0x11; //ox12 x 5 - same on the Receiver chip and the RX-RF_Address above if EN_AA is enabled!!!
  173.     }
  174.     //-------WriteToNrf(W, TX_ADDR, val, 5);
  175.  
  176.     //Payload width Setup - 1-32byte (how many bytes to send per transmission)
  177.     val[0]=0x05; //Send 5 bytes per package this time (same on receiver and transmitter)
  178.     WriteToNrf(W,RX_PW_P0,val,1);
  179.  
  180.     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,
  181.     //and if payload >1Sbyte in 2Hbps) "F" is number of retries (1-15, now 15)
  182.     WriteToNrf(W, SETUP_RETR, val, 1);
  183.  
  184.     //CONFIG reg setup - Now it's time to boot up the Qgf and choose if it's suppose to be a transmitter or receiver
  185.     val[0]=0x1E; //0b0001 1110 - bit 0="0":transmitter bit 0="1":Receiver, bit 1="1"=power up,
  186.     //bit 4="1"= mask_Max_RT i.e. IRQ-interrupt is not triggered if transmission failed.
  187.     WriteToNrf(W, CONFIG, val, 1);
  188.  
  189.     //device need 1.5ms to reach standby mode (CE=low)
  190.     _delay_ms(100);
  191.  
  192.     // Sei ();
  193. }
  194.  
  195. // The receiver opens and "Listening" in 1s
  196. void  receive_payload ( void )
  197. {
  198.     //sei();        // Enable global interrupt
  199.    
  200.     SETBIT(PORTB,1);    // CE IR_High = "Listening"
  201.     _delay_ms(1000);    // listening in 1s and received goes int0-interruptvektor Started
  202.     CLEARBIT(PORTB,1);  // ce low back-stop listening
  203.    
  204.     //cli();    // Disable the global interrupt
  205. }
  206.  
  207. // Send the data
  208. void transmit_payload( uint8_t  *W_buff)
  209. {
  210.     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 ...
  211.     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!)
  212.    
  213.     //sei();    // enable global interrupt already!
  214.     // USART_Transmit (GetReg (STATUS));
  215.    
  216.     _delay_ms(10);      // need to be really ms, not us?? YEEES! otherwise it will not work!
  217.     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
  218.     _delay_us ( 20 );       // at least 10us!
  219.     CLEARBIT(PORTB,1);  // CE low
  220.     _delay_ms(10);      // need to be really ms, not us?? YEEES! otherwise it will not work!
  221.    
  222.     // Cli (); // Disable the global interrupt ... ajabaja, then closes USART_RX-listening to!
  223.    
  224. }
  225.  
  226.  
  227.  
  228. int main(void)
  229. {
  230.     lcd_init(LCD_DISP_ON);
  231.     lcd_puts("LCD init");
  232.     _delay_ms(500);
  233.     lcd_clrscr();
  234.    
  235.     InitSPI();
  236.     lcd_puts("SPI init");
  237.     _delay_ms(500);
  238.     lcd_clrscr();
  239.    
  240.     ioinit();
  241.     INT0_interrupt_init();
  242.     lcd_puts("INT0 init");
  243.     _delay_ms(500);
  244.     lcd_clrscr();
  245.    
  246.     nrf24L01_init();
  247.     lcd_puts("NRF init");
  248.     _delay_ms(500);
  249.     lcd_clrscr();
  250.    
  251.     ////uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
  252.     ////lcd_puts("USART init");
  253.     ////_delay_ms(500);
  254.     ////lcd_clrscr();  
  255.    
  256.     //sei();
  257.    
  258.     //Clear the screen
  259.     lcd_clrscr();
  260.    
  261. char buffer[5];
  262.  
  263.  
  264. lcd_puts("STATUS:");
  265. itoa( GetReg(STATUS), buffer, 16);   // convert interger into string (decimal format)
  266. lcd_puts(buffer);        // and transmit string to UART
  267. _delay_ms(500);
  268. lcd_clrscr();
  269.  
  270. lcd_puts("TEST:");
  271. itoa(0xBC, buffer, 16);   // convert interger into string (decimal format)
  272. lcd_puts(buffer);        // and transmit string to UART
  273. _delay_ms(500);
  274. lcd_clrscr();
  275.  
  276.  
  277. lcd_puts("EA_AA:");
  278. itoa( GetReg(EN_AA), buffer, 16);   // convert interger into string (decimal format)
  279. lcd_puts(buffer);        // and transmit string to UART
  280. _delay_ms(500);
  281. lcd_clrscr();
  282.  
  283.  
  284. lcd_puts("EN_RXADDR:");
  285. itoa( GetReg(EN_RXADDR), buffer, 16);   // convert interger into string (decimal format)
  286. lcd_puts(buffer);        // and transmit string to UART
  287. _delay_ms(500);
  288. lcd_clrscr();
  289.  
  290.  
  291. lcd_puts("SETUP_AW:");
  292. itoa( GetReg(SETUP_AW), buffer, 16);   // convert interger into string (decimal format)
  293. lcd_puts(buffer);        // and transmit string to UART
  294. _delay_ms(500);
  295. lcd_clrscr();
  296.  
  297.  
  298. lcd_puts("RF_CH:");
  299. itoa( GetReg(RF_CH), buffer, 16);   // convert interger into string (decimal format)
  300. lcd_puts(buffer);        // and transmit string to UART
  301. _delay_ms(500);
  302. lcd_clrscr();
  303.  
  304.  
  305. lcd_puts("RF_SETUP:");
  306. itoa( GetReg(RF_SETUP), buffer, 16);   // convert interger into string (decimal format)
  307. lcd_puts(buffer);        // and transmit string to UART
  308. _delay_ms(500);
  309. lcd_clrscr();
  310.  
  311.  
  312. lcd_puts("RX_ADDR_P0:");
  313. itoa( GetReg(RX_ADDR_P0), buffer, 16);   // convert interger into string (decimal format)
  314. lcd_puts(buffer);        // and transmit string to UART
  315. _delay_ms(500);
  316. lcd_clrscr();
  317.  
  318.  
  319. lcd_puts("TX_ADDR:");
  320. itoa( GetReg(TX_ADDR), buffer, 16);   // convert interger into string (decimal format)
  321. lcd_puts(buffer);        // and transmit string to UART
  322. _delay_ms(500);
  323. lcd_clrscr();
  324.  
  325.  
  326. lcd_puts("RX_PW_P0:");
  327. itoa( GetReg(RX_PW_P0), buffer, 16);   // convert interger into string (decimal format)
  328. lcd_puts(buffer);        // and transmit string to UART
  329. _delay_ms(500);
  330. lcd_clrscr();
  331.  
  332.  
  333. lcd_puts("SETUP_RETR:");
  334. itoa( GetReg(SETUP_RETR), buffer, 16);   // convert interger into string (decimal format)
  335. lcd_puts(buffer);        // and transmit string to UART
  336. _delay_ms(500);
  337. lcd_clrscr();
  338.  
  339.  
  340. lcd_puts("CONFIG:");
  341. itoa( GetReg(CONFIG), buffer, 16);   // convert interger into string (decimal format)
  342. lcd_puts(buffer);        // and transmit string to UART
  343. _delay_ms(500);
  344. lcd_clrscr();
  345.  
  346.     while(1){
  347.     reset();
  348.    
  349.     int i;
  350.     for (i=0;i<5;i++)
  351.     {
  352.         buffer[i]=0x93;
  353.     }
  354.     transmit_payload(buffer);
  355.    
  356.     lcd_puts("STATUS:");
  357.     itoa( GetReg(STATUS), buffer, 16);   // convert interger into string (decimal format)
  358.     lcd_puts(buffer);        // and transmit string to UART
  359.     _delay_ms(500);
  360.     lcd_clrscr();
  361.  
  362.     }
  363.    
  364.     return 0;
  365. }
  366.  
  367.  
  368.  
  369.  
  370. 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!
  371. {
  372.     cli();  // Disable the global interrupt
  373.     CLEARBIT(PORTB ,1);         // ce low back-stop listening / transmitting
  374.     SETBIT(PORTB,0);  // part one
  375.     _delay_ms(500);
  376.     CLEARBIT(PORTB,0);  // led off
  377.     // Receiver function to print out on usart:
  378.     data = WriteToNrf (R, R_RX_PAYLOAD, data, DataLen); // Read the received data
  379.     reset();
  380.     for (int i = 0; i <DataLen; i++)
  381.     {
  382.         lcd_putc(data[i]);
  383.     }
  384.     _delay_ms(1000);
  385. lcd_clrscr();
  386.     sei();
  387. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement