radio_config.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /**
  2. * Copyright (c) 2009 - 2018, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. /** @file
  41. * @addtogroup nrf_dev_radio_rx_example_main nrf_dev_radio_tx_example_main
  42. * @{
  43. */
  44. #include "radio_config.h"
  45. #include "nrf_delay.h"
  46. /* These are set to zero as ShockBurst packets don't have corresponding fields. */
  47. #define PACKET_S1_FIELD_SIZE (0UL) /**< Packet S1 field size in bits. */
  48. #define PACKET_S0_FIELD_SIZE (0UL) /**< Packet S0 field size in bits. */
  49. #define PACKET_LENGTH_FIELD_SIZE (0UL) /**< Packet length field size in bits. */
  50. /**
  51. * @brief Function for swapping/mirroring bits in a byte.
  52. *
  53. *@verbatim
  54. * output_bit_7 = input_bit_0
  55. * output_bit_6 = input_bit_1
  56. * :
  57. * output_bit_0 = input_bit_7
  58. *@endverbatim
  59. *
  60. * @param[in] inp is the input byte to be swapped.
  61. *
  62. * @return
  63. * Returns the swapped/mirrored input byte.
  64. */
  65. static uint32_t swap_bits(uint32_t inp);
  66. /**
  67. * @brief Function for swapping bits in a 32 bit word for each byte individually.
  68. *
  69. * The bits are swapped as follows:
  70. * @verbatim
  71. * output[31:24] = input[24:31]
  72. * output[23:16] = input[16:23]
  73. * output[15:8] = input[8:15]
  74. * output[7:0] = input[0:7]
  75. * @endverbatim
  76. * @param[in] input is the input word to be swapped.
  77. *
  78. * @return
  79. * Returns the swapped input byte.
  80. */
  81. static uint32_t bytewise_bitswap(uint32_t inp);
  82. static uint32_t swap_bits(uint32_t inp)
  83. {
  84. uint32_t i;
  85. uint32_t retval = 0;
  86. inp = (inp & 0x000000FFUL);
  87. for (i = 0; i < 8; i++)
  88. {
  89. retval |= ((inp >> i) & 0x01) << (7 - i);
  90. }
  91. return retval;
  92. }
  93. static uint32_t bytewise_bitswap(uint32_t inp)
  94. {
  95. return (swap_bits(inp >> 24) << 24)
  96. | (swap_bits(inp >> 16) << 16)
  97. | (swap_bits(inp >> 8) << 8)
  98. | (swap_bits(inp));
  99. }
  100. /**
  101. * @brief Function for configuring the radio to operate in ShockBurst compatible mode.
  102. *
  103. * To configure the application running on nRF24L series devices:
  104. *
  105. * @verbatim
  106. * uint8_t tx_address[5] = { 0xC0, 0x01, 0x23, 0x45, 0x67 };
  107. * hal_nrf_set_rf_channel(7);
  108. * hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
  109. * hal_nrf_set_address(HAL_NRF_TX, tx_address);
  110. * hal_nrf_set_address(HAL_NRF_PIPE0, tx_address);
  111. * hal_nrf_open_pipe(0, false);
  112. * hal_nrf_set_datarate(HAL_NRF_1MBPS);
  113. * hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
  114. * hal_nrf_setup_dynamic_payload(0xFF);
  115. * hal_nrf_enable_dynamic_payload(false);
  116. * @endverbatim
  117. *
  118. * When transmitting packets with hal_nrf_write_tx_payload(const uint8_t *tx_pload, uint8_t length),
  119. * match the length with PACKET_STATIC_LENGTH.
  120. * hal_nrf_write_tx_payload(payload, PACKET_STATIC_LENGTH);
  121. *
  122. */
  123. void radio_configure()
  124. {
  125. // Radio config
  126. NRF_RADIO->TXPOWER = (RADIO_TXPOWER_TXPOWER_0dBm << RADIO_TXPOWER_TXPOWER_Pos);
  127. NRF_RADIO->FREQUENCY = 7UL; // Frequency bin 7, 2407MHz
  128. NRF_RADIO->MODE = (RADIO_MODE_MODE_Nrf_1Mbit << RADIO_MODE_MODE_Pos);
  129. // Radio address config
  130. NRF_RADIO->PREFIX0 =
  131. ((uint32_t)swap_bits(0xC3) << 24) // Prefix byte of address 3 converted to nRF24L series format
  132. | ((uint32_t)swap_bits(0xC2) << 16) // Prefix byte of address 2 converted to nRF24L series format
  133. | ((uint32_t)swap_bits(0xC1) << 8) // Prefix byte of address 1 converted to nRF24L series format
  134. | ((uint32_t)swap_bits(0xC0) << 0); // Prefix byte of address 0 converted to nRF24L series format
  135. NRF_RADIO->PREFIX1 =
  136. ((uint32_t)swap_bits(0xC7) << 24) // Prefix byte of address 7 converted to nRF24L series format
  137. | ((uint32_t)swap_bits(0xC6) << 16) // Prefix byte of address 6 converted to nRF24L series format
  138. | ((uint32_t)swap_bits(0xC4) << 0); // Prefix byte of address 4 converted to nRF24L series format
  139. NRF_RADIO->BASE0 = bytewise_bitswap(0x01234567UL); // Base address for prefix 0 converted to nRF24L series format
  140. NRF_RADIO->BASE1 = bytewise_bitswap(0x89ABCDEFUL); // Base address for prefix 1-7 converted to nRF24L series format
  141. NRF_RADIO->TXADDRESS = 0x00UL; // Set device address 0 to use when transmitting
  142. NRF_RADIO->RXADDRESSES = 0x01UL; // Enable device address 0 to use to select which addresses to receive
  143. // Packet configuration
  144. NRF_RADIO->PCNF0 = (PACKET_S1_FIELD_SIZE << RADIO_PCNF0_S1LEN_Pos) |
  145. (PACKET_S0_FIELD_SIZE << RADIO_PCNF0_S0LEN_Pos) |
  146. (PACKET_LENGTH_FIELD_SIZE << RADIO_PCNF0_LFLEN_Pos); //lint !e845 "The right argument to operator '|' is certain to be 0"
  147. // Packet configuration
  148. NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) |
  149. (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) |
  150. (PACKET_BASE_ADDRESS_LENGTH << RADIO_PCNF1_BALEN_Pos) |
  151. (PACKET_STATIC_LENGTH << RADIO_PCNF1_STATLEN_Pos) |
  152. (PACKET_PAYLOAD_MAXSIZE << RADIO_PCNF1_MAXLEN_Pos); //lint !e845 "The right argument to operator '|' is certain to be 0"
  153. // CRC Config
  154. NRF_RADIO->CRCCNF = (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos); // Number of checksum bits
  155. if ((NRF_RADIO->CRCCNF & RADIO_CRCCNF_LEN_Msk) == (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos))
  156. {
  157. NRF_RADIO->CRCINIT = 0xFFFFUL; // Initial value
  158. NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16 + x^12^x^5 + 1
  159. }
  160. else if ((NRF_RADIO->CRCCNF & RADIO_CRCCNF_LEN_Msk) == (RADIO_CRCCNF_LEN_One << RADIO_CRCCNF_LEN_Pos))
  161. {
  162. NRF_RADIO->CRCINIT = 0xFFUL; // Initial value
  163. NRF_RADIO->CRCPOLY = 0x107UL; // CRC poly: x^8 + x^2^x^1 + 1
  164. }
  165. }
  166. /**
  167. * @}
  168. */