Advertisement
phillip_bourdon234

NRF24L01_Driver.c

Feb 28th, 2021
558
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.89 KB | None | 0 0
  1. #include "stm32f10x.h"
  2. #include "GPIO_Driver.h"
  3. #include "SPI_drive.h"
  4. #include "NRF_Driver.h"
  5. #include "delay.h"
  6.  
  7. const int static CSN_DELAY_TIME = 25; //This is the delay time, in micro seconds, that is required before
  8.                                //bringing the CSN pin high. I don't really know why I have to delay
  9.                                                              //for such a short amount of time right before the CSN pin is pulled high.
  10.                                                              //I know it's not an spi timing issue because an spi read/write
  11.                                                              //can be called multiple times before writing high to the CSN pin.
  12.                                                              //I also tried reducing the speed of the CSN pin down to 2Mhz; however,
  13.                                                              //this change had no effect.
  14.  
  15. GPIO_TYPE static CE;
  16. GPIO_TYPE  static CSN;
  17.  
  18. void nrf_init_pins(GPIO_TypeDef *CE_port, uint32_t CE_pin, GPIO_TypeDef *CSN_port, uint32_t CSN_pin)
  19. {
  20.     //configure the CE pin
  21.     CE.port = CE_port;
  22.     CE.pin = CE_pin;
  23.     CE.mode = OUTPUT;
  24.     CE.mode_type = OUTPUT_GEN_PURPOSE;
  25.     CE.speed = SPEED_50MHZ;
  26.    
  27.     //configure the CSN pin
  28.     CSN.port = CSN_port;
  29.     CSN.pin = CSN_pin;
  30.     CSN.mode = OUTPUT;
  31.     CSN.mode_type = OUTPUT_GEN_PURPOSE;
  32.     CSN.speed = SPEED_50MHZ;   
  33.  
  34.     init_gpio(CE);
  35.     init_gpio(CSN);
  36.    
  37.     pin_write(CE.port, CE.pin, LOW); //bring CE Low
  38.  
  39.     pin_write(CSN.port, CSN.pin, HIGH);  //bring CSN HIGH
  40.    
  41.     spi_init_master();
  42.    
  43. }  
  44.  
  45. void nrf_write_reg(char reg, char data)
  46. {
  47.         pin_write(CSN.port, CSN.pin, LOW);
  48.        
  49.         spi_write(W_REGISTER | reg);
  50.        
  51.         spi_write(data);
  52.    
  53.         delayUs(CSN_DELAY_TIME);
  54.         pin_write(CSN.port, CSN.pin, HIGH);
  55.    
  56. }
  57.  
  58. uint8_t nrf_read_reg(char reg)
  59. {
  60.         uint8_t reg_data = 0;
  61.    
  62.         pin_write(CSN.port, CSN.pin, LOW);
  63.        
  64.         spi_write(R_REGISTER | reg);
  65.        
  66.         spi_write(0xF1); //send dumby byte in order to recieve the data inside the reg
  67.        
  68.         delayUs(CSN_DELAY_TIME);
  69.         pin_write(CSN.port, CSN.pin, HIGH);
  70.        
  71.         reg_data = spi_read();
  72.    
  73.         return reg_data;
  74. }
  75.  
  76. void nrf_init_transmiter(uint32_t addr_high, uint8_t addr_low, uint8_t channel, char en_auot_ack, char en_dpl)
  77. {
  78.     nrf_cmd_clear_interrupts();
  79.    
  80.     nrf_write_reg(NRF_CONFIG, 0x7A);
  81.     delayMs(100);
  82.  
  83.     nrf_write_reg(EN_AA, 0x3F);
  84.    
  85.     nrf_write_reg(EN_RXADDR, 0x03);
  86.    
  87.     nrf_write_reg(SETUP_AW, 0x03);
  88.    
  89.     nrf_write_reg(SETUP_RETR, 0xFF);
  90.    
  91.     nrf_write_reg(RF_CH, channel);
  92.    
  93.     nrf_write_reg(RF_SETUP, 0x0F);
  94.        
  95.     nrf_set_tx_addr(addr_high, addr_low, en_auot_ack);
  96.        
  97.     if (en_dpl)
  98.     {
  99.         nrf_cmd_activate();
  100.         nrf_write_reg_specific_bit(FEATURE, EN_DPL, 1);  
  101.         nrf_write_reg_specific_bit(DYNPD, PIPE_0, 1);      
  102.     }
  103. }
  104.  
  105. void nrf_init_reciever(uint8_t pipe, uint32_t addr_high, uint8_t addr_low, uint8_t channel, char en_auto_ack, char en_dpl, uint8_t dpl_w)
  106. {
  107.     nrf_cmd_clear_interrupts();
  108.    
  109.     nrf_write_reg(NRF_CONFIG, 0x7B);
  110.     delayMs(100);
  111.    
  112.     nrf_write_reg(EN_AA, 0x3F);
  113.  
  114.     nrf_write_reg(SETUP_AW, 0x03);
  115.    
  116.     nrf_write_reg(SETUP_RETR, 0xFF);
  117.    
  118.     nrf_write_reg(RF_CH, channel);
  119.    
  120.     nrf_write_reg(RF_SETUP, 0x0F);
  121.        
  122.     nrf_write_reg_specific_bit(EN_RXADDR, pipe, 1); //enable rx pipe
  123.     nrf_set_rx_addr(pipe, addr_high, addr_low);     //set address          
  124.    
  125.     if (en_dpl == 1) //if dynamic payload width is enabled
  126.     {
  127.         nrf_cmd_activate();
  128.         nrf_write_reg_specific_bit(FEATURE, EN_DPL, 1); //enable dynamic PL feature
  129.         nrf_write_reg_specific_bit(DYNPD, pipe, 1);     //enable dynamic PL for pipe
  130.        
  131.         //auto ack has to be enabled if using dynamic payload
  132.         nrf_write_reg_specific_bit(EN_AA, pipe, 1); //enable auto ack on pipe  
  133.     }
  134.     else
  135.     {
  136.         nrf_write_reg((pipe + RX_PW_OFFSET), dpl_w);   //write the static payload width
  137.        
  138.         //if using static PL width use can still use auto ack but now its optional
  139.         if(en_auto_ack)
  140.         {  
  141.             nrf_write_reg_specific_bit(EN_AA, ENAA_P1, 1);  //enable auto ack on pipe 1
  142.             nrf_write_reg_specific_bit(EN_AA, pipe, 1);     //enable auto ack on pipe
  143.         }
  144.     }
  145. }
  146.  
  147. void nrf_write_reg_specific_bit(uint8_t reg, uint8_t bit, uint8_t value)
  148. {  
  149.     //READ
  150.     uint8_t reg_value =  nrf_read_reg(reg);
  151.    
  152.     //MODIFY
  153.     if (value == 1)
  154.     {
  155.         reg_value |= (1 << bit);
  156.     }
  157.     else
  158.     {
  159.         reg_value &= ~(1 << bit);
  160.     }
  161.        
  162.     //WRITE
  163.     nrf_write_reg(reg, reg_value);
  164. }
  165.  
  166. void nrf_read_reg_multiple_bytes(uint8_t reg, uint8_t *data_buff)
  167. {
  168.     pin_write(CSN.port, CSN.pin, LOW);
  169.    
  170.     spi_write(reg);
  171.    
  172.     spi_write(0xF1);
  173.     data_buff[0] = spi_read();
  174.    
  175.     spi_write(0xF1);
  176.     data_buff[1] = spi_read();
  177.    
  178.     spi_write(0xF1);
  179.     data_buff[2] = spi_read();
  180.    
  181.     spi_write(0xF1);
  182.     data_buff[3] = spi_read();
  183.    
  184.     spi_write(0xF1);
  185.     data_buff[4] = spi_read();
  186.    
  187.     delayUs(CSN_DELAY_TIME);
  188.     pin_write(CSN.port, CSN.pin, HIGH);
  189. }
  190.  
  191. void nrf_cmd_listen(void)
  192. {
  193.     pin_write(CE.port, CE.pin, HIGH); //bring CE pin HIGH
  194. }
  195.  
  196. uint8_t nrf_cmd_get_status(void)
  197. {
  198.     return nrf_read_reg(0x07);
  199. }
  200.  
  201. void nrf_cmd_clear_interrupts(void)
  202. {
  203.     nrf_write_reg(0x07, 0x70);
  204. }
  205.  
  206. void nrf_cmd_flush_tx(void)
  207. {
  208.     pin_write(CSN.port, CSN.pin, LOW);
  209.        
  210.     spi_write(0xE1);
  211.        
  212.     delayUs(CSN_DELAY_TIME);
  213.     pin_write(CSN.port, CSN.pin, HIGH);
  214. }
  215.  
  216. void nrf_cmd_flush_rx(void)
  217. {
  218.     pin_write(CSN.port, CSN.pin, LOW);
  219.        
  220.     spi_write(0xE2);
  221.        
  222.     delayUs(CSN_DELAY_TIME);
  223.     pin_write(CSN.port, CSN.pin, HIGH);
  224. }
  225.  
  226. void nrf_cmd_act_as_RX(void)
  227. {
  228.     nrf_write_reg_specific_bit(0x00, 0, 1);
  229. }
  230.  
  231. void nrf_cmd_act_as_TX(void)
  232. {
  233.     nrf_write_reg_specific_bit(0x00, 0, 0);
  234. }
  235.  
  236. //  The activate command (0x50) followed by 0x73 makes the following commands writable.
  237. //  • R_RX_PL_WID
  238. //  • W_ACK_PAYLOAD
  239. //  • W_TX_PAYLOAD_NOACK
  240. void nrf_cmd_activate(void)
  241. {
  242.     pin_write(CSN.port, CSN.pin, LOW);
  243.    
  244.     spi_write(0x50);
  245.        
  246.     spi_write(0x73);
  247.    
  248.     delayUs(CSN_DELAY_TIME);
  249.     pin_write(CSN.port, CSN.pin, HIGH);
  250. }
  251.  
  252. void nrf_set_tx_addr(uint32_t addr_high, uint8_t addr_low, uint8_t auto_ack)
  253. {
  254.     pin_write(CSN.port, CSN.pin, LOW);  //start SPI comms by a LOW on CSN
  255.        
  256.     spi_write(0x20 | 0x10);
  257.        
  258.  
  259.     /*  5 byte address is devided into a uint8_t low byte
  260.      *  and a uint32_t high byte
  261.      *  since the SPI can only send 1 byte at a time
  262.      *  we first send the low byte
  263.      *  and then extract the other bytes from the uint32
  264.      *  and send them one by one LSB first
  265.      */
  266.    
  267.     spi_write(addr_low);
  268.  
  269.     spi_write(addr_high & 0xFF);
  270.  
  271.     spi_write((addr_high >> 8) & 0xFF);
  272.  
  273.     spi_write((addr_high >> 16) & 0xFF);
  274.  
  275.     spi_write((addr_high >> 24) & 0xFF);
  276.    
  277.     delayUs(CSN_DELAY_TIME);
  278.     pin_write(CSN.port, CSN.pin, HIGH);
  279.    
  280.     /* If auto ack is enabled then the same address that was written
  281.      * to TX_ADDR above must also be written to PIPE 0 because that
  282.      * is the pipe that it will receive the auto ack on. This cannot
  283.      * be changed it is hardwaired to receive acks on pipe 0 */
  284.    
  285.     if (auto_ack)
  286.     {  
  287.         nrf_write_reg_specific_bit(0x01, 0, 1); //enable auto ack on pipe 0
  288.         pin_write(CSN.port, CSN.pin, LOW);
  289.  
  290.         //write address into pipe 0
  291.       spi_write(0x20 | 0x0A);
  292.  
  293.         spi_write(addr_low);
  294.  
  295.         spi_write(addr_high & 0xFF);
  296.  
  297.         spi_write((addr_high >> 8) & 0xFF);
  298.  
  299.         spi_write((addr_high >> 16) & 0xFF);
  300.  
  301.         spi_write((addr_high >> 24) & 0xFF);
  302.  
  303.         delayUs(CSN_DELAY_TIME);
  304.         pin_write(CSN.port, CSN.pin, HIGH);  //end spi
  305.     }  
  306. }
  307.  
  308. void nrf_set_rx_addr(uint8_t rx_pipe, uint32_t addr_high, uint8_t addr_low)
  309. {  
  310.     if (rx_pipe > 1) // because pipe 0 and 1 just need to written directly with 5 bytes
  311.     {
  312.             //RX_ADDR_P# is offest by 10 = RX_ADDR_OFFSET with the pipe number
  313.             //NRF_cmd_write_entire_reg((rx_pipe + RX_ADDR_OFFSET), addr_low);  //for pipe 2 to 5
  314.             nrf_write_reg(rx_pipe + 10, addr_low);
  315.     }
  316.     else
  317.     {
  318.         pin_write(CSN.port, CSN.pin, LOW);
  319.  
  320.         //write address into pipe 0
  321.       spi_write(0x20 | (rx_pipe + 10));
  322.  
  323.         spi_write(addr_low);
  324.  
  325.         spi_write(addr_high & 0xFF);
  326.  
  327.         spi_write((addr_high >> 8) & 0xFF);
  328.  
  329.         spi_write((addr_high >> 16) & 0xFF);
  330.  
  331.         spi_write((addr_high >> 24) & 0xFF);
  332.        
  333.         delayUs(CSN_DELAY_TIME);
  334.         pin_write(CSN.port, CSN.pin, HIGH); //end spi
  335.     }
  336. }
  337.  
  338.  
  339. void nrf_read_rx_payload(uint8_t *payload)
  340. {
  341.     uint8_t payload_width = nrf_read_reg(0x60);
  342.    
  343.     pin_write(CE.port, CE.pin, LOW);//bring CE LOW to stop listening
  344.    
  345.     pin_write(CSN.port, CSN.pin, LOW); //start SPI
  346.    
  347.     spi_write(0x61); //command that tells the NRF to send the data in the RX_PLD register to us
  348.  
  349.     for(int i = 0; i < payload_width; i++)
  350.     {
  351.         spi_write(0x61); //idk if this value has to be 0x61 or if its just a dumby byte in order to read
  352.         payload[i] = spi_read();
  353.     }
  354.    
  355.     pin_write(CE.port, CE.pin, HIGH); //end SPI
  356.    
  357.     delayUs(CSN_DELAY_TIME);
  358.     pin_write(CSN.port, CSN.pin, HIGH);//bring CE HIGH to start listening again
  359. }
  360.  
  361. void nrf_write_tx_payload(uint8_t *data, uint8_t length)
  362. {  
  363.     pin_write(CE.port, CE.pin, LOW); //bring CE LOW to stop listening
  364.    
  365.     pin_write(CSN.port, CSN.pin, LOW); //start SPI
  366.    
  367.     spi_write(0xA0); //send the W_TX_PAYLOAD command    
  368.  
  369.     for(int i = 0; i < length; i++)
  370.     {
  371.         spi_write(data[i]);
  372.     }
  373.      
  374.     delayUs(CSN_DELAY_TIME);
  375.     pin_write(CSN.port, CSN.pin, HIGH); //end SPI
  376.  
  377.     //CE set high to start transmition if in TX mode
  378.     // must be held high for a bit then back low
  379.     pin_write(CE.port, CE.pin, HIGH);
  380.     delayUs(20); //this was here for debugging purposes feel free to delete or insert your own
  381.     pin_write(CE.port, CE.pin, LOW);
  382.    
  383.     nrf_cmd_get_status();
  384.    
  385. }
  386.  
  387. char nrf_send(uint8_t *payload, uint8_t length)
  388. {
  389.     uint8_t status = 0;
  390.    
  391.     nrf_write_tx_payload(payload, length);
  392.     delayMs(10);
  393.     status = nrf_cmd_get_status();
  394.    
  395.     if(status & 0x20)
  396.     {
  397.         nrf_cmd_clear_interrupts();
  398.         nrf_cmd_flush_tx();
  399.         delayMs(10);
  400.         return 1;
  401.     }
  402.     else if(status & 0x10)
  403.     {
  404.         nrf_cmd_clear_interrupts();
  405.         nrf_cmd_flush_tx();
  406.         delayMs(10);
  407.         return 0;
  408.     }
  409.     else if(status & 0x01)
  410.     {
  411.         nrf_cmd_flush_tx();
  412.         delayMs(10);
  413.         return 0;
  414.     }
  415.     else
  416.     {
  417.         delayMs(100);
  418.         return 0;
  419.     }
  420. }
  421.  
  422. char nrf_data_available(void)
  423. {
  424.     if((nrf_cmd_get_status() & RX_DR)){
  425.         nrf_cmd_clear_interrupts();
  426.         return 1;
  427.     }
  428.     else{
  429.         nrf_cmd_clear_interrupts();
  430.         return 0;
  431.     }
  432. }
  433.  
  434. void nrf_read(uint8_t *dataBuffer)
  435. {
  436.     nrf_read_rx_payload(dataBuffer);
  437.        
  438.     nrf_cmd_flush_rx();
  439.        
  440.     nrf_cmd_listen();
  441. }
  442.  
  443.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement