Guest User

Untitled

a guest
Sep 13th, 2015
195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 19.13 KB | None | 0 0
  1. /*************************************************************
  2. ************* nRF24 Skeye MINI Tx Code  ******************
  3. **************************************************************
  4.  
  5. by solata
  6.  
  7. Thanks to:
  8. deviationTX team (on which code this is based)
  9.  
  10. This program is free software: you can redistribute it and/or modify
  11. it under the terms of the GNU General Public License as published by
  12. the Free Software Foundation, either version 3 of the License, or
  13. (at your option) any later version.
  14.  
  15. This program is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. GNU General Public License for more details.
  19.  
  20. You should have received a copy of the GNU General Public License.
  21. If not, see <http://www.gnu.org/licenses/>.
  22. */
  23.  
  24. #include <util/atomic.h>
  25.  
  26. ///////////////////
  27. // pinout
  28.  
  29. #define PPM_pin   2             // PPM in
  30. //Spi Comm.pins with nRF24l01
  31. #define MOSI_pin  5             // MOSI-D5
  32. #define SCK_pin   4             // SCK-D4
  33. #define CS_pin    6             // CS-D6
  34. #define CE_pin    3             // CE-D3
  35. #define MISO_pin  7             // MISO-D7
  36.  
  37. //---------------------------------
  38. // spi outputs
  39. #define  CS_on PORTD |= 0x40    // PORTD6
  40. #define  CS_off PORTD &= 0xBF   // PORTD6
  41. #define  CE_on PORTD |= 0x08    // PORTD3
  42. #define  CE_off PORTD &= 0xF7   // PORTD3
  43. //
  44. #define  SCK_on PORTD |= 0x10   // PORTD4
  45. #define  SCK_off PORTD &= 0xEF  // PORTD4
  46. #define  MOSI_on PORTD |= 0x20  // PORTD5
  47. #define  MOSI_off PORTD &= 0xDF // PORTD5
  48. // spi input
  49. #define  MISO_on (PIND & 0x80)  // PORTD7
  50.  
  51. //
  52. #define _NOP() __asm__ __volatile__("nop"); __asm__ __volatile__("nop");
  53. #define BV(bit) (1 << bit)
  54.  
  55. #define GREEN_PACKET_LENGTH 15
  56. #define BLUE_PACKET_LENGTH 19
  57. #define RF_BIND_CHANNEL 0x02
  58. #define BIND_COUNT 3000
  59. #define NUM_RF_CHANNELS    4
  60. #define BLUE_PACKET_PERIOD 6000
  61. #define GREEN_PACKET_PERIOD 1500
  62. static const uint8_t tx_rx_id[] = {0xCC,0xCC,0xCC,0xCC,0xCC};
  63.  
  64. #define PPM_MIN 1000
  65. #define PPM_MIN_COMMAND 1250
  66. #define PPM_MID 1500
  67. #define PPM_MAX_COMMAND 1750
  68. #define PPM_MAX 2000
  69.  
  70. // PPM stream settings
  71. #define CHANNELS 6
  72. enum chan_order{  // TAER -> Spektrum chan order
  73.     THROTTLE,
  74.     AILERON,
  75.     ELEVATOR,
  76.     RUDDER,
  77.     AUX1,  // mode (3 positions, highest position is headless on CX10-A)
  78.     AUX2,  // flip control
  79. };
  80.  
  81. enum{
  82.     CX10_GREEN,
  83.     CX10_BLUE, // also compatible with CX10-A, CX12
  84. };
  85.  
  86. ////////////////
  87. // Variables
  88. static uint8_t board_type = CX10_GREEN; // board type, change as required
  89.  
  90. static uint8_t txid[4]; // transmitter ID
  91. static uint8_t freq[4]; // frequency hopping table
  92. static uint8_t packet[BLUE_PACKET_LENGTH];
  93. static uint8_t packet_length;
  94. static uint32_t packet_period;
  95. volatile uint16_t Servo_data[CHANNELS] = {0,};
  96. static uint16_t ppm[CHANNELS] = {PPM_MIN,PPM_MIN,PPM_MIN,PPM_MIN,};
  97. static uint8_t current_chan = 0;
  98. static uint8_t ledPin = 13;
  99.  
  100. ////////////////
  101. // nRF24 Register map
  102. enum {
  103.     NRF24L01_00_CONFIG      = 0x00,
  104.     NRF24L01_01_EN_AA       = 0x01,
  105.     NRF24L01_02_EN_RXADDR   = 0x02,
  106.     NRF24L01_03_SETUP_AW    = 0x03,
  107.     NRF24L01_04_SETUP_RETR  = 0x04,
  108.     NRF24L01_05_RF_CH       = 0x05,
  109.     NRF24L01_06_RF_SETUP    = 0x06,
  110.     NRF24L01_07_STATUS      = 0x07,
  111.     NRF24L01_08_OBSERVE_TX  = 0x08,
  112.     NRF24L01_09_CD          = 0x09,
  113.     NRF24L01_0A_RX_ADDR_P0  = 0x0A,
  114.     NRF24L01_0B_RX_ADDR_P1  = 0x0B,
  115.     NRF24L01_0C_RX_ADDR_P2  = 0x0C,
  116.     NRF24L01_0D_RX_ADDR_P3  = 0x0D,
  117.     NRF24L01_0E_RX_ADDR_P4  = 0x0E,
  118.     NRF24L01_0F_RX_ADDR_P5  = 0x0F,
  119.     NRF24L01_10_TX_ADDR     = 0x10,
  120.     NRF24L01_11_RX_PW_P0    = 0x11,
  121.     NRF24L01_12_RX_PW_P1    = 0x12,
  122.     NRF24L01_13_RX_PW_P2    = 0x13,
  123.     NRF24L01_14_RX_PW_P3    = 0x14,
  124.     NRF24L01_15_RX_PW_P4    = 0x15,
  125.     NRF24L01_16_RX_PW_P5    = 0x16,
  126.     NRF24L01_17_FIFO_STATUS = 0x17,
  127.     NRF24L01_1C_DYNPD       = 0x1C,
  128.     NRF24L01_1D_FEATURE     = 0x1D,
  129.     //Instructions
  130.     NRF24L01_61_RX_PAYLOAD  = 0x61,
  131.     NRF24L01_A0_TX_PAYLOAD  = 0xA0,
  132.     NRF24L01_E1_FLUSH_TX    = 0xE1,
  133.     NRF24L01_E2_FLUSH_RX    = 0xE2,
  134.     NRF24L01_E3_REUSE_TX_PL = 0xE3,
  135.     NRF24L01_50_ACTIVATE    = 0x50,
  136.     NRF24L01_60_R_RX_PL_WID = 0x60,
  137.     NRF24L01_B0_TX_PYLD_NOACK = 0xB0,
  138.     NRF24L01_FF_NOP         = 0xFF,
  139.     NRF24L01_A8_W_ACK_PAYLOAD0 = 0xA8,
  140.     NRF24L01_A8_W_ACK_PAYLOAD1 = 0xA9,
  141.     NRF24L01_A8_W_ACK_PAYLOAD2 = 0xAA,
  142.     NRF24L01_A8_W_ACK_PAYLOAD3 = 0xAB,
  143.     NRF24L01_A8_W_ACK_PAYLOAD4 = 0xAC,
  144.     NRF24L01_A8_W_ACK_PAYLOAD5 = 0xAD,
  145. };
  146.  
  147. // Bit mnemonics
  148. enum {
  149.     NRF24L01_00_MASK_RX_DR  = 6,
  150.     NRF24L01_00_MASK_TX_DS  = 5,
  151.     NRF24L01_00_MASK_MAX_RT = 4,
  152.     NRF24L01_00_EN_CRC      = 3,
  153.     NRF24L01_00_CRCO        = 2,
  154.     NRF24L01_00_PWR_UP      = 1,
  155.     NRF24L01_00_PRIM_RX     = 0,
  156.  
  157.     NRF24L01_07_RX_DR       = 6,
  158.     NRF24L01_07_TX_DS       = 5,
  159.     NRF24L01_07_MAX_RT      = 4,
  160.  
  161.     NRF2401_1D_EN_DYN_ACK   = 0,
  162.     NRF2401_1D_EN_ACK_PAY   = 1,
  163.     NRF2401_1D_EN_DPL       = 2,
  164. };
  165.  
  166. // Bitrates
  167. enum {
  168.     NRF24L01_BR_1M = 0,
  169.     NRF24L01_BR_2M,
  170.     NRF24L01_BR_250K,
  171.     NRF24L01_BR_RSVD
  172. };
  173.  
  174. enum TXRX_State {
  175.     TXRX_OFF,
  176.     TX_EN,
  177.     RX_EN,
  178. };
  179.  
  180. /////////////////
  181. // setup
  182. void setup() {
  183.     randomSeed((analogRead(A0) & 0x1F) | (analogRead(A1) << 5));
  184.     for(uint8_t i=0;i<4;i++) {
  185.         txid[i] = random();
  186.     }
  187.     pinMode(ledPin, OUTPUT);
  188.     //PPM input from transmitter port
  189.     pinMode(PPM_pin, INPUT);
  190.     //RF module pins
  191.     pinMode(MOSI_pin, OUTPUT);
  192.     pinMode(SCK_pin, OUTPUT);
  193.     pinMode(CS_pin, OUTPUT);
  194.     pinMode(CE_pin, OUTPUT);
  195.     pinMode(MISO_pin, INPUT);
  196.     digitalWrite(ledPin, LOW);//start LED off
  197.     CS_on;//start CS high
  198.     CE_on;//start CE high
  199.     MOSI_on;//start MOSI high
  200.     SCK_on;//start sck high
  201.     delay(70);//wait 70ms
  202.     CS_off;//start CS low
  203.     CE_off;//start CE low
  204.     MOSI_off;//start MOSI low
  205.     SCK_off;//start sck low
  206.     delay(100);
  207.     CS_on;//start CS high
  208.     delay(500);
  209.    
  210.     NRF24L01_Reset();
  211.     delay(500);
  212.     NRF24L01_Initialize();
  213.     delay(150);
  214.     CX10_init();
  215.     delay(50);
  216.     //Bind to Receiver
  217.     CX10_bind();
  218. }
  219.  
  220. ///////////////
  221. // main loop
  222. void loop() {
  223.     uint32_t timeout;
  224.    
  225.     timeout = process_CX10();
  226.     while(micros() < timeout)
  227.     {   };
  228. }
  229.  
  230. char freq1[8] = {0x09,0x09,0x20,0x20,0x30,0x30,0x40,0x40};
  231. char freq2[8] = {0x11,0x11,0x21,0x21,0x31,0x31,0x41,0x41};
  232. ///////////////
  233. // CX10 functions
  234. void CX10_init()
  235. {
  236.     int i = 0;
  237.     int j = 0;
  238.    
  239.     txid[1] %= 0x30;
  240.     /*freq[0] = (txid[0] & 0x0F) + 0x03;
  241.     freq[1] = (txid[0] >> 4) + 0x16;
  242.     freq[2] = (txid[1] & 0x0F) + 0x2D;
  243.     freq[3] = (txid[1] >> 4) + 0x40;*/
  244.        
  245.     current_chan = 0;
  246.     NRF24L01_Reset();
  247.     NRF24L01_Initialize();
  248.     NRF24L01_SetTxRxMode(TX_EN);
  249.     //delay(1000);
  250.     //XN297_SetTXAddr(tx_rx_id,5);
  251.     //XN297_SetRXAddr(tx_rx_id,5);
  252.     delay(500);
  253.     NRF24L01_ReadReg(NRF24L01_07_STATUS);
  254.     NRF24L01_WriteReg(NRF24L01_09_CD, 0x00);
  255.     NRF24L01_WriteReg(NRF24L01_08_OBSERVE_TX, 0x00);
  256.     NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x77);
  257.     NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, 0x22);
  258.     NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x10);
  259.     NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00);
  260.     NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);
  261.     NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x00);
  262.     NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00);
  263.     NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x4e);
  264.     NRF24L01_ReadReg(0x1D);
  265.     NRF24L01_Activate(0x73);
  266.     NRF24L01_ReadReg(NRF24L01_07_STATUS);
  267.  
  268.     NRF24L01_Activate(0x53); // magic for BK2421 bank switch
  269.  
  270.     /*NRF24L01_WriteRegisterMulti(0x00, (u8 *) "\x40\x4B\x01\xE2", 4);
  271.     NRF24L01_WriteRegisterMulti(0x01, (u8 *) "\xC0\x4B\x00\x00", 4);
  272.     NRF24L01_WriteRegisterMulti(0x02, (u8 *) "\xD0\xFC\x8C\x02", 4);
  273.     NRF24L01_WriteRegisterMulti(0x03, (u8 *) "\x99\x00\x39\x21", 4);
  274.     NRF24L01_WriteRegisterMulti(0x04, (u8 *) "\xD9\x96\x8A\xDB", 4);
  275.     NRF24L01_WriteRegisterMulti(0x05, (u8 *) "\x24\x06\x0F\xB6", 4);
  276.     NRF24L01_WriteRegisterMulti(0x06, (u8 *) "\x00\x00\x00\x00", 4);
  277.     NRF24L01_WriteRegisterMulti(0x07, (u8 *) "\x00\x00\x00\x00", 4);
  278.     NRF24L01_WriteRegisterMulti(0x08, (u8 *) "\x00\x00\x00\x00", 4);
  279.     NRF24L01_WriteRegisterMulti(0x09, (u8 *) "\x00\x00\x00\x00", 4);
  280.     NRF24L01_WriteRegisterMulti(0x0A, (u8 *) "\x00\x00\x00\x00", 4);
  281.     NRF24L01_WriteRegisterMulti(0x0B, (u8 *) "\x00\x00\x00\x00", 4);
  282.     NRF24L01_WriteRegisterMulti(0x0C, (u8 *) "\x00\x12\x73\x00", 4);
  283.     NRF24L01_WriteRegisterMulti(0x0D, (u8 *) "\x36\xB4\x80\x00", 4);
  284.     NRF24L01_WriteRegisterMulti(0x0E, (u8 *) "\x41\x20\x08\x04\x81\x20\xCF\xF7\xFE\xFF\xFF", 11);*/
  285.    
  286.     NRF24L01_ReadReg(NRF24L01_07_STATUS);
  287.     NRF24L01_Activate(0x53);
  288.  
  289.     NRF24L01_ReadReg(NRF24L01_00_CONFIG);
  290.  
  291.     NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (u8 *) "\xAB\xAC\xAD\xAE\xAF", 5);
  292.    
  293.    
  294.     delayMicroseconds(4000);
  295.  
  296.     for (i = 0; i < 12; i++) {
  297.  
  298.       for (j = 0; j < 8; j++) {
  299.         NRF24L01_WriteReg(NRF24L01_05_RF_CH, freq1[current_chan++]);
  300.         current_chan %= 8;
  301.         NRF24L01_WritePayload((u8 *) "\xA1\xF4\x30\x57\x47\xAA\xAA\xBB\xB1\xD4", 10);  
  302.         delayMicroseconds(4200);
  303.       }
  304.       for (j = 0; j < 8; j++) {
  305.         NRF24L01_WriteReg(NRF24L01_05_RF_CH, freq1[current_chan++]);
  306.         current_chan %= 8;
  307.         NRF24L01_WritePayload((u8 *) "\x0A\x1A\x2A\x3A\x12\x22\x32\x42\xB1\x46", 10);  
  308.         delayMicroseconds(4200);
  309.       }
  310.     }
  311. }
  312.  
  313. void CX10_bind()
  314. {
  315.     uint16_t counter=BIND_COUNT;
  316.     bool bound=false;
  317.     uint32_t timeout;
  318.  
  319.     NRF24L01_ReadReg(NRF24L01_07_STATUS);
  320.     NRF24L01_WriteReg(NRF24L01_09_CD, 0x00);
  321.     NRF24L01_WriteReg(NRF24L01_08_OBSERVE_TX, 0x00);
  322.     NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x77);
  323.     NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, 0x27);
  324.     NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x10);
  325.     NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00);
  326.     NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);
  327.     NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x00);
  328.     NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00);
  329.     NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x4e);
  330.     NRF24L01_ReadReg(0x1D);
  331.     NRF24L01_Activate(0x73);
  332.     NRF24L01_ReadReg(NRF24L01_07_STATUS);
  333.  
  334.     NRF24L01_Activate(0x53); // magic for BK2421 bank switch
  335.  
  336.     /*NRF24L01_WriteRegisterMulti(0x00, (u8 *) "\x40\x4B\x01\xE2", 4);
  337.     NRF24L01_WriteRegisterMulti(0x01, (u8 *) "\xC0\x4B\x00\x00", 4);
  338.     NRF24L01_WriteRegisterMulti(0x02, (u8 *) "\xD0\xFC\x8C\x02", 4);
  339.     NRF24L01_WriteRegisterMulti(0x03, (u8 *) "\x99\x00\x39\x21", 4);
  340.     NRF24L01_WriteRegisterMulti(0x04, (u8 *) "\xF9\x96\x8A\xDB", 4);
  341.     NRF24L01_WriteRegisterMulti(0x05, (u8 *) "\x24\x06\x0F\xB6", 4);
  342.     NRF24L01_WriteRegisterMulti(0x06, (u8 *) "\x00\x00\x00\x00", 4);
  343.     NRF24L01_WriteRegisterMulti(0x07, (u8 *) "\x00\x00\x00\x00", 4);
  344.     NRF24L01_WriteRegisterMulti(0x08, (u8 *) "\x00\x00\x00\x00", 4);
  345.     NRF24L01_WriteRegisterMulti(0x09, (u8 *) "\x00\x00\x00\x00", 4);
  346.     NRF24L01_WriteRegisterMulti(0x0A, (u8 *) "\x00\x00\x00\x00", 4);
  347.     NRF24L01_WriteRegisterMulti(0x0B, (u8 *) "\x00\x00\x00\x00", 4);
  348.     NRF24L01_WriteRegisterMulti(0x0C, (u8 *) "\x00\x12\x73\x00", 4);
  349.     NRF24L01_WriteRegisterMulti(0x0D, (u8 *) "\x36\xB4\x80\x00", 4);
  350.     NRF24L01_WriteRegisterMulti(0x0E, (u8 *) "\x41\x20\x08\x04\x81\x20\xCF\xF7\xFE\xFF\xFF", 11);*/
  351.    
  352.     NRF24L01_ReadReg(NRF24L01_07_STATUS);
  353.     NRF24L01_Activate(0x53);
  354.     NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (u8 *) "\x47\x57\x30\xF4\xA1", 5);
  355.  
  356.     //NRF24L01_WriteReg(NRF24L01_05_RF_CH, freq2[current_chan++]);
  357.     //current_chan %= 8;
  358.     //NRF24L01_FlushTx();
  359.  
  360.     //NRF24L01_WritePayload((u8 *) "\x00\x00\x00\x00\x00\x45\x00\x21\x00\xb9", 10);
  361.    
  362.    
  363.     /*while(!bound) {
  364.         NRF24L01_SetTxRxMode(TX_EN);
  365.         XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP));
  366.         NRF24L01_WriteReg(NRF24L01_05_RF_CH, RF_BIND_CHANNEL);
  367.         NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
  368.         NRF24L01_FlushTx();
  369.         CX10_Write_Packet(0xAA); // send bind packet
  370.         switch(board_type) {
  371.             case CX10_GREEN:
  372.                 if(counter==0)
  373.                     bound = true;
  374.                 delayMicroseconds(packet_period);
  375.                 break;
  376.             case CX10_BLUE:    
  377.                 delay(1);
  378.                 CE_off;
  379.                 NRF24L01_SetTxRxMode(RX_EN);
  380.                 NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
  381.                 NRF24L01_FlushRx();
  382.                 XN297_Configure(BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP) | BV(NRF24L01_00_PRIM_RX));
  383.                 CE_on;
  384.                 timeout = millis()+5;
  385.                 while(millis()<timeout) {
  386.                     if(NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) { // data received from aircraft
  387.                         XN297_ReadPayload(packet, packet_length);
  388.                         if( packet[9] == 0x01)
  389.                             bound = true;
  390.                         break;
  391.                     }
  392.                 }                
  393.                 break;
  394.         }
  395.         digitalWrite(ledPin, counter-- & 0x10);
  396.     }
  397.     digitalWrite(ledPin, HIGH);*/
  398. }
  399.  
  400. uint32_t process_CX10()
  401. {
  402.     uint32_t nextPacket = micros() + 4200;
  403.  
  404.     NRF24L01_WriteReg(NRF24L01_05_RF_CH, freq2[current_chan++]);
  405.     current_chan %= 8;
  406.  
  407.     NRF24L01_WritePayload((u8 *) "\x00\x00\x00\x00\x00\x45\x00\x21\x00\xb9", 10);
  408.     return nextPacket;
  409. }
  410.  
  411.  
  412. ///////////////
  413. // SPI
  414.  
  415. void Read_Packet(uint8_t *data, uint8_t length)
  416. {
  417.     uint8_t i;
  418.     CS_off;
  419.     _spi_write(0x61); // Read RX payload
  420.     for (i=0;i<length;i++) {
  421.         data[i]=_spi_read();
  422.     }
  423.     CS_on;
  424. }
  425.  
  426. uint8_t _spi_write(uint8_t command)
  427. {
  428.     uint8_t result=0;
  429.     uint8_t n=8;
  430.     SCK_off;
  431.     MOSI_off;
  432.     while(n--) {
  433.         if(command & 0x80)
  434.             MOSI_on;
  435.         else
  436.             MOSI_off;
  437.         if(MISO_on)
  438.             result |= 0x01;
  439.         SCK_on;
  440.         _NOP();
  441.         SCK_off;
  442.         command = command << 1;
  443.         result = result << 1;
  444.     }
  445.     MOSI_on;
  446.     return result;
  447. }
  448.  
  449. void _spi_write_address(uint8_t address, uint8_t data)
  450. {
  451.     CS_off;
  452.     _spi_write(address);
  453.     _NOP();
  454.     _spi_write(data);
  455.     CS_on;
  456. }
  457.  
  458. uint8_t _spi_read()
  459. {
  460.     uint8_t result=0;
  461.     uint8_t i;
  462.     MOSI_off;
  463.     _NOP();
  464.     for(i=0;i<8;i++) {
  465.         if(MISO_on) // if MISO is HIGH
  466.             result = (result<<1)|0x01;
  467.         else
  468.             result = result<<1;
  469.         SCK_on;
  470.         _NOP();
  471.         SCK_off;
  472.         _NOP();
  473.     }
  474.     return result;
  475. }
  476.  
  477. uint8_t _spi_read_address(uint8_t address)
  478. {
  479.     uint8_t result;
  480.     CS_off;
  481.     _spi_write(address);
  482.     result = _spi_read();
  483.     CS_on;
  484.     return(result);
  485. }
  486.  
  487. ///////////////
  488. // nRF24
  489.  
  490. /* Instruction Mnemonics */
  491. #define R_REGISTER    0x00
  492. #define W_REGISTER    0x20
  493. #define REGISTER_MASK 0x1F
  494. #define ACTIVATE      0x50
  495. #define R_RX_PL_WID   0x60
  496. #define R_RX_PAYLOAD  0x61
  497. #define W_TX_PAYLOAD  0xA0
  498. #define W_ACK_PAYLOAD 0xA8
  499. #define FLUSH_TX      0xE1
  500. #define FLUSH_RX      0xE2
  501. #define REUSE_TX_PL   0xE3
  502. #define NOP           0xFF
  503.  
  504. static uint8_t rf_setup;
  505.  
  506. uint8_t NRF24L01_WriteReg(uint8_t address, uint8_t data)
  507. {
  508.     CS_off;
  509.     _spi_write_address(address | W_REGISTER, data);
  510.     CS_on;
  511.     return 1;
  512. }
  513.  
  514. void NRF24L01_WriteRegisterMulti(uint8_t address, const uint8_t data[], uint8_t len)
  515. {
  516.     delayMicroseconds(5);
  517.     CS_off;
  518.     _spi_write(address | W_REGISTER);
  519.     for(uint8_t i=0;i<len;i++)
  520.         _spi_write(data[i]);
  521.     CS_on;
  522.     delayMicroseconds(5);
  523. }
  524.  
  525. void NRF24L01_Initialize()
  526. {
  527.     rf_setup = 0x0F;
  528. }
  529.  
  530. uint8_t NRF24L01_FlushTx()
  531. {
  532.     return Strobe(FLUSH_TX);
  533. }
  534.  
  535. uint8_t NRF24L01_FlushRx()
  536. {
  537.     return Strobe(FLUSH_RX);
  538. }
  539.  
  540. static uint8_t Strobe(uint8_t state)
  541. {
  542.     uint8_t result;
  543.     CS_off;
  544.     result = _spi_write(state);
  545.     CS_on;
  546.     return result;
  547. }
  548.  
  549. uint8_t NRF24L01_WritePayload(uint8_t *data, uint8_t length)
  550. {
  551.     CE_off;
  552.     CS_off;
  553.     _spi_write(W_TX_PAYLOAD);
  554.     for(uint8_t i=0; i<length; i++)
  555.         _spi_write(data[i]);
  556.     CS_on;
  557.     CE_on; // transmit
  558.     return 1;
  559. }
  560.  
  561. uint8_t NRF24L01_ReadPayload(uint8_t *data, uint8_t length)
  562. {
  563.     uint8_t i;
  564.     CS_off;
  565.     _spi_write(R_RX_PAYLOAD); // Read RX payload
  566.     for (i=0;i<length;i++) {
  567.         data[i]=_spi_read();
  568.     }
  569.     CS_on;
  570.     return 1;
  571. }
  572.  
  573. uint8_t NRF24L01_ReadReg(uint8_t reg)
  574. {
  575.     CS_off;
  576.     uint8_t data = _spi_read_address(reg);
  577.     CS_on;
  578.     return data;
  579. }
  580.  
  581. uint8_t NRF24L01_Activate(uint8_t code)
  582. {
  583.     CS_off;
  584.     _spi_write(ACTIVATE);
  585.     _spi_write(code);
  586.     CS_on;
  587.     return 1;
  588. }
  589.  
  590. void NRF24L01_SetTxRxMode(uint8_t mode)
  591. {
  592.     if(mode == TX_EN) {
  593.         CE_off;
  594.         NRF24L01_WriteReg(NRF24L01_07_STATUS,
  595.                     (1 << NRF24L01_07_RX_DR)    //reset the flag(s)
  596.                   | (1 << NRF24L01_07_TX_DS)
  597.                   | (1 << NRF24L01_07_MAX_RT));
  598.         NRF24L01_WriteReg(NRF24L01_00_CONFIG,
  599.                     (1 << NRF24L01_00_EN_CRC)   // switch to TX mode
  600.                   | (1 << NRF24L01_00_CRCO)
  601.                   | (1 << NRF24L01_00_PWR_UP));
  602.         delayMicroseconds(130);
  603.         CE_on;
  604.     } else if (mode == RX_EN) {
  605.         CE_off;
  606.         NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);        // reset the flag(s)
  607.         NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0F);        // switch to RX mode
  608.         NRF24L01_WriteReg(NRF24L01_07_STATUS,
  609.                     (1 << NRF24L01_07_RX_DR)    //reset the flag(s)
  610.                   | (1 << NRF24L01_07_TX_DS)
  611.                   | (1 << NRF24L01_07_MAX_RT));
  612.         NRF24L01_WriteReg(NRF24L01_00_CONFIG,
  613.                     (1 << NRF24L01_00_EN_CRC)   // switch to RX mode
  614.                   | (1 << NRF24L01_00_CRCO)
  615.                   | (1 << NRF24L01_00_PWR_UP)
  616.                   | (1 << NRF24L01_00_PRIM_RX));
  617.         delayMicroseconds(130);
  618.         CE_on;
  619.     } else {
  620.         NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC)); //PowerDown
  621.         CE_off;
  622.     }
  623. }
  624.  
  625. uint8_t NRF24L01_Reset()
  626. {
  627.     NRF24L01_FlushTx(); //E1
  628.     NRF24L01_FlushRx(); //E2
  629.     uint8_t status1 = Strobe(0xFF); // NOP
  630.     uint8_t status2 = NRF24L01_ReadReg(0x07);  // read status 0x07 00
  631.     NRF24L01_SetTxRxMode(TXRX_OFF); // 20 08
  632.     return (status1 == status2 && (status1 & 0x0f) == 0x0e);
  633. }
  634.  
  635. // Power is in range 0..3 for nRF24L01
  636. uint8_t NRF24L01_SetPower(uint8_t power)
  637. {
  638.     rf_setup = (rf_setup & 0xF9) | ((power & 0x03) << 1);
  639.     return NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup);
  640. }
  641.  
  642. uint8_t NRF24L01_SetBitrate(uint8_t bitrate)
  643. {
  644.     // Note that bitrate 250kbps (and bit RF_DR_LOW) is valid only
  645.     // for nRF24L01+. There is no way to programmatically tell it from
  646.     // older version, nRF24L01, but the older is practically phased out
  647.     // by Nordic, so we assume that we deal with with modern version.
  648.  
  649.     // Bit 0 goes to RF_DR_HIGH, bit 1 - to RF_DR_LOW
  650.     rf_setup = (rf_setup & 0xD7) | ((bitrate & 0x02) << 4) | ((bitrate & 0x01) << 3);
  651.     return NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup);
  652. }
Advertisement
Add Comment
Please, Sign In to add comment