Advertisement
Q009

Untitled

Aug 7th, 2015
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.52 KB | None | 0 0
  1. #include <string.h>
  2. #include "radio.h"
  3.  
  4. extern "C" {
  5.     #include "nrf_delay.h"
  6. }
  7.  
  8. static uint8_t radio_packet[RADIO_PACKET_TOTAL_SIZE] = { 0 }, radio_state = RADIO_OFF;
  9. static uint16_t radio_frequency = 0;
  10.  
  11. void radio_init() {
  12.     NRF_TIMER2->TASKS_STOP  = 1;
  13.     NRF_TIMER2->TASKS_CLEAR = 1;
  14.     NRF_TIMER2->MODE        = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos;
  15.     NRF_TIMER2->BITMODE     = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
  16.     NRF_TIMER2->PRESCALER   = 4;
  17.    
  18.     radio_state = RADIO_IDLE;
  19. }
  20.  
  21. void radio_configure() {
  22.     if (radio_state == RADIO_OFF) return;
  23.    
  24.     NRF_RADIO->PREFIX0     = 0xC0C1C2C3;
  25.     NRF_RADIO->PREFIX1     = 0xC4C5C6C7;
  26.     NRF_RADIO->BASE0       = 0x01234567;
  27.     NRF_RADIO->BASE1       = 0x89ABCDEF;
  28.     NRF_RADIO->TXADDRESS   = 0;
  29.     NRF_RADIO->RXADDRESSES = RADIO_RXADDRESSES_ADDR0_Enabled << RADIO_RXADDRESSES_ADDR0_Pos;
  30.     NRF_RADIO->PCNF0       = (0UL << RADIO_PCNF0_S1LEN_Pos) |
  31.                              (0UL << RADIO_PCNF0_S0LEN_Pos) |
  32.                              (8UL << RADIO_PCNF0_LFLEN_Pos);
  33.     NRF_RADIO->PCNF1       = (RADIO_PCNF1_WHITEEN_Disabled      << RADIO_PCNF1_WHITEEN_Pos) |
  34.                              (RADIO_PCNF1_ENDIAN_Big            << RADIO_PCNF1_ENDIAN_Pos ) |
  35.                              (4UL                               << RADIO_PCNF1_BALEN_Pos  ) |
  36.                              (0UL                               << RADIO_PCNF1_STATLEN_Pos) |
  37.                              (uint32_t(RADIO_PACKET_TOTAL_SIZE) << RADIO_PCNF1_MAXLEN_Pos );
  38.     NRF_RADIO->CRCCNF      = RADIO_CRCCNF_LEN_Three        << RADIO_CRCCNF_LEN_Pos;
  39.     //NRF_RADIO->SHORTS      = RADIO_SHORTS_READY_START_Msk  << RADIO_SHORTS_READY_START_Pos;
  40.     NRF_RADIO->TXPOWER     = RADIO_TXPOWER_TXPOWER_Pos4dBm << RADIO_TXPOWER_TXPOWER_Pos;
  41.     NRF_RADIO->MODE        = RADIO_MODE_MODE_Nrf_2Mbit     << RADIO_MODE_MODE_Pos;
  42.     NRF_RADIO->FREQUENCY   = 40;
  43. }
  44.  
  45. void radio_disable() {
  46.     if (radio_state == RADIO_OFF || radio_state == RADIO_IDLE) return;
  47.    
  48.     NRF_RADIO->EVENTS_DISABLED = 0;
  49.     NRF_RADIO->TASKS_DISABLE = 1;
  50.     while (!NRF_RADIO->EVENTS_DISABLED) nrf_delay_us(1);
  51.     radio_state = RADIO_IDLE;
  52. }
  53.  
  54. bool radio_do_work(uint16_t timeout_us = 0) {
  55.     NRF_RADIO->EVENTS_END = 0;
  56.     NRF_RADIO->PACKETPTR = (uint32_t)radio_packet;
  57.     NRF_RADIO->TASKS_START = 1;
  58.     if (timeout_us) {
  59.         NRF_TIMER2->CC[0]       = timeout_us;
  60.         NRF_TIMER2->TASKS_START = 1;
  61.     }
  62.    
  63.     while (!NRF_RADIO->EVENTS_END) {
  64.         if (timeout_us && NRF_TIMER2->EVENTS_COMPARE[0]) {
  65.             NRF_RADIO->TASKS_STOP         = 1;
  66.             NRF_TIMER2->EVENTS_COMPARE[0] = 0;
  67.             NRF_TIMER2->TASKS_STOP        = 1;
  68.             NRF_TIMER2->TASKS_CLEAR       = 1;
  69.             return false;
  70.         }
  71.         nrf_delay_us(1);
  72.     }
  73.  
  74.     return true;
  75. }
  76.  
  77. inline void radio_set_frequency() {
  78.     NRF_RADIO->FREQUENCY = radio_frequency;
  79. }
  80.  
  81. void radio_set_channel(uint8_t channel) {
  82.     if (radio_state != RADIO_IDLE) return;
  83.    
  84.     radio_frequency = channel * RADIO_CHANNEL_WIDTH;
  85.     if (radio_frequency > 80) radio_frequency = 80 - (80 % RADIO_CHANNEL_WIDTH);
  86.     radio_set_frequency();
  87. }
  88.  
  89. void radio_transmit() {
  90.     if (radio_state != RADIO_TX) {
  91.         NRF_RADIO->EVENTS_READY = 0;
  92.         NRF_RADIO->TASKS_TXEN   = 1;
  93.         while (!NRF_RADIO->EVENTS_READY) nrf_delay_us(1);
  94.         radio_state = RADIO_TX;
  95.     }
  96.     radio_do_work();
  97. }
  98.  
  99. bool radio_send(uint8_t *data, uint8_t length) {
  100.     if (radio_state == RADIO_OFF || !data || !length || length > RADIO_MAX_PACKET_SIZE) return false;
  101.     radio_packet[RADIO_PACKET_LENGTH_BYTE] = length + RADIO_PACKET_RESERVED_BYTES;
  102.     memcpy(&radio_packet[RADIO_PACKET_RESERVED_BYTES], data, length);
  103.     radio_transmit();
  104.     return true;
  105. }
  106.  
  107. bool radio_recv(uint8_t *data, uint8_t &length, uint16_t timeout_us) {
  108.     if (radio_state == RADIO_OFF || !data || !length) return false;
  109.    
  110.     if (radio_state != RADIO_RX) {
  111.         NRF_RADIO->EVENTS_READY = 0;
  112.         NRF_RADIO->TASKS_RXEN   = 1;
  113.         while (!NRF_RADIO->EVENTS_READY) nrf_delay_us(1);
  114.         radio_state = RADIO_RX;
  115.     }
  116.    
  117.     if (!radio_do_work(timeout_us)) return false;
  118.    
  119.     if (NRF_RADIO->CRCSTATUS) {
  120.         uint8_t packet_length = radio_packet[RADIO_PACKET_LENGTH_BYTE] - RADIO_PACKET_RESERVED_BYTES;
  121.         if (packet_length < length) length = packet_length;
  122.         memcpy(data, &radio_packet[RADIO_PACKET_RESERVED_BYTES], length);
  123.         return true;
  124.     }
  125.    
  126.     return false;
  127. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement