Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nRF51822_esb by
micro_esb.c@0:a01a54c0dc90, 2015-03-23 (annotated)
- Committer:
- joshuajnoble
- Date:
- Mon Mar 23 04:09:41 2015 +0000
- Revision:
- 0:a01a54c0dc90
- Child:
- 1:5d49c7b9f405
trying esb
Who changed what in which revision?
| User | Revision | Line number | New contents of line | 
|---|---|---|---|
| joshuajnoble | 0:a01a54c0dc90 | 1 | /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. | 
| joshuajnoble | 0:a01a54c0dc90 | 2 | * | 
| joshuajnoble | 0:a01a54c0dc90 | 3 | * The information contained herein is property of Nordic Semiconductor ASA. | 
| joshuajnoble | 0:a01a54c0dc90 | 4 | * Terms and conditions of usage are described in detail in NORDIC | 
| joshuajnoble | 0:a01a54c0dc90 | 5 | * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. | 
| joshuajnoble | 0:a01a54c0dc90 | 6 | * | 
| joshuajnoble | 0:a01a54c0dc90 | 7 | * Licensees are granted free, non-transferable use of the information. NO | 
| joshuajnoble | 0:a01a54c0dc90 | 8 | * WARRANTY of ANY KIND is provided. This heading must NOT be removed from | 
| joshuajnoble | 0:a01a54c0dc90 | 9 | * the file. | 
| joshuajnoble | 0:a01a54c0dc90 | 10 | * | 
| joshuajnoble | 0:a01a54c0dc90 | 11 | */ | 
| joshuajnoble | 0:a01a54c0dc90 | 12 | |
| joshuajnoble | 0:a01a54c0dc90 | 13 | #include "micro_esb.h" | 
| joshuajnoble | 0:a01a54c0dc90 | 14 | #include "uesb_error_codes.h" | 
| joshuajnoble | 0:a01a54c0dc90 | 15 | //#include "nrf_gpio.h" | 
| joshuajnoble | 0:a01a54c0dc90 | 16 | #include <string.h> | 
| joshuajnoble | 0:a01a54c0dc90 | 17 | |
| joshuajnoble | 0:a01a54c0dc90 | 18 | |
| joshuajnoble | 0:a01a54c0dc90 | 19 | static uesb_event_handler_t m_event_handler; | 
| joshuajnoble | 0:a01a54c0dc90 | 20 | |
| joshuajnoble | 0:a01a54c0dc90 | 21 | // RF parameters | 
| joshuajnoble | 0:a01a54c0dc90 | 22 | static uesb_config_t m_config_local; | 
| joshuajnoble | 0:a01a54c0dc90 | 23 | |
| joshuajnoble | 0:a01a54c0dc90 | 24 | // TX FIFO | 
| joshuajnoble | 0:a01a54c0dc90 | 25 | static uesb_payload_t m_tx_fifo_payload[UESB_CORE_TX_FIFO_SIZE]; | 
| joshuajnoble | 0:a01a54c0dc90 | 26 | static uesb_payload_tx_fifo_t m_tx_fifo; | 
| joshuajnoble | 0:a01a54c0dc90 | 27 | |
| joshuajnoble | 0:a01a54c0dc90 | 28 | // RX FIFO | 
| joshuajnoble | 0:a01a54c0dc90 | 29 | static uesb_payload_t m_rx_fifo_payload[UESB_CORE_RX_FIFO_SIZE]; | 
| joshuajnoble | 0:a01a54c0dc90 | 30 | static uesb_payload_rx_fifo_t m_rx_fifo; | 
| joshuajnoble | 0:a01a54c0dc90 | 31 | |
| joshuajnoble | 0:a01a54c0dc90 | 32 | static uint8_t m_tx_payload_buffer[UESB_CORE_MAX_PAYLOAD_LENGTH + 2]; | 
| joshuajnoble | 0:a01a54c0dc90 | 33 | static uint8_t m_rx_payload_buffer[UESB_CORE_MAX_PAYLOAD_LENGTH + 2]; | 
| joshuajnoble | 0:a01a54c0dc90 | 34 | |
| joshuajnoble | 0:a01a54c0dc90 | 35 | // Run time variables | 
| joshuajnoble | 0:a01a54c0dc90 | 36 | static volatile uint32_t m_interrupt_flags = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 37 | static uint32_t m_pid = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 38 | static volatile uint32_t m_retransmits_remaining; | 
| joshuajnoble | 0:a01a54c0dc90 | 39 | static volatile uint32_t m_last_tx_attempts; | 
| joshuajnoble | 0:a01a54c0dc90 | 40 | static volatile uint8_t m_last_rx_packet_pid = 0xFF; | 
| joshuajnoble | 0:a01a54c0dc90 | 41 | static volatile uint32_t m_last_rx_packet_crc = 0xFFFFFFFF; | 
| joshuajnoble | 0:a01a54c0dc90 | 42 | static volatile uint32_t m_wait_for_ack_timeout_us; | 
| joshuajnoble | 0:a01a54c0dc90 | 43 | |
| joshuajnoble | 0:a01a54c0dc90 | 44 | static uesb_payload_t *current_payload; | 
| joshuajnoble | 0:a01a54c0dc90 | 45 | |
| joshuajnoble | 0:a01a54c0dc90 | 46 | static uesb_mainstate_t m_uesb_mainstate = UESB_STATE_UNINITIALIZED; | 
| joshuajnoble | 0:a01a54c0dc90 | 47 | |
| joshuajnoble | 0:a01a54c0dc90 | 48 | // Constant parameters | 
| joshuajnoble | 0:a01a54c0dc90 | 49 | #define RX_WAIT_FOR_ACK_TIMEOUT_US_2MBPS 48 // Smallest reliable value - 43 | 
| joshuajnoble | 0:a01a54c0dc90 | 50 | #define RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS 64 // Smallest reliable value - 59 | 
| joshuajnoble | 0:a01a54c0dc90 | 51 | #define RX_WAIT_FOR_ACK_TIMEOUT_US_250KBPS 250 | 
| joshuajnoble | 0:a01a54c0dc90 | 52 | |
| joshuajnoble | 0:a01a54c0dc90 | 53 | // Macros | 
| joshuajnoble | 0:a01a54c0dc90 | 54 | #define DISABLE_RF_IRQ NVIC_DisableIRQ(RADIO_IRQn) | 
| joshuajnoble | 0:a01a54c0dc90 | 55 | #define ENABLE_RF_IRQ NVIC_EnableIRQ(RADIO_IRQn) | 
| joshuajnoble | 0:a01a54c0dc90 | 56 | |
| joshuajnoble | 0:a01a54c0dc90 | 57 | #define RADIO_SHORTS_COMMON ( RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | \ | 
| joshuajnoble | 0:a01a54c0dc90 | 58 | RADIO_SHORTS_ADDRESS_RSSISTART_Msk | RADIO_SHORTS_DISABLED_RSSISTOP_Msk ) | 
| joshuajnoble | 0:a01a54c0dc90 | 59 | |
| joshuajnoble | 0:a01a54c0dc90 | 60 | // These function pointers are changed dynamically, depending on protocol configuration and state | 
| joshuajnoble | 0:a01a54c0dc90 | 61 | static void (*on_radio_disabled)(void) = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 62 | static void (*on_radio_end)(void) = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 63 | static void (*update_rf_payload_format)(uint32_t payload_length) = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 64 | |
| joshuajnoble | 0:a01a54c0dc90 | 65 | // The following functions are assigned to the function pointers above | 
| joshuajnoble | 0:a01a54c0dc90 | 66 | static void on_radio_disabled_esb_dpl_tx_noack(void); | 
| joshuajnoble | 0:a01a54c0dc90 | 67 | static void on_radio_disabled_esb_dpl_tx(void); | 
| joshuajnoble | 0:a01a54c0dc90 | 68 | static void on_radio_disabled_esb_dpl_tx_wait_for_ack(void); | 
| joshuajnoble | 0:a01a54c0dc90 | 69 | static void on_radio_disabled_esb_dpl_rx(void); | 
| joshuajnoble | 0:a01a54c0dc90 | 70 | static void on_radio_disabled_esb_dpl_rx_ack(void); | 
| joshuajnoble | 0:a01a54c0dc90 | 71 | |
| joshuajnoble | 0:a01a54c0dc90 | 72 | static void on_radio_end_sb_tx(void); | 
| joshuajnoble | 0:a01a54c0dc90 | 73 | static void on_radio_end_sb_rx(void); | 
| joshuajnoble | 0:a01a54c0dc90 | 74 | |
| joshuajnoble | 0:a01a54c0dc90 | 75 | static void update_rf_payload_format_esb_dpl(uint32_t payload_length) | 
| joshuajnoble | 0:a01a54c0dc90 | 76 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 77 | #if(UESB_CORE_MAX_PAYLOAD_LENGTH <= 32) | 
| joshuajnoble | 0:a01a54c0dc90 | 78 | NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S0LEN_Pos) | (6 << RADIO_PCNF0_LFLEN_Pos) | (3 << RADIO_PCNF0_S1LEN_Pos); | 
| joshuajnoble | 0:a01a54c0dc90 | 79 | #else | 
| joshuajnoble | 0:a01a54c0dc90 | 80 | NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S0LEN_Pos) | (8 << RADIO_PCNF0_LFLEN_Pos) | (3 << RADIO_PCNF0_S1LEN_Pos); | 
| joshuajnoble | 0:a01a54c0dc90 | 81 | #endif | 
| joshuajnoble | 0:a01a54c0dc90 | 82 | NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | | 
| joshuajnoble | 0:a01a54c0dc90 | 83 | (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | | 
| joshuajnoble | 0:a01a54c0dc90 | 84 | ((m_config_local.rf_addr_length - 1) << RADIO_PCNF1_BALEN_Pos) | | 
| joshuajnoble | 0:a01a54c0dc90 | 85 | (0 << RADIO_PCNF1_STATLEN_Pos) | | 
| joshuajnoble | 0:a01a54c0dc90 | 86 | (UESB_CORE_MAX_PAYLOAD_LENGTH << RADIO_PCNF1_MAXLEN_Pos); | 
| joshuajnoble | 0:a01a54c0dc90 | 87 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 88 | |
| joshuajnoble | 0:a01a54c0dc90 | 89 | static void update_rf_payload_format_esb(uint32_t payload_length) | 
| joshuajnoble | 0:a01a54c0dc90 | 90 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 91 | NRF_RADIO->PCNF0 = (1 << RADIO_PCNF0_S0LEN_Pos) | (0 << RADIO_PCNF0_LFLEN_Pos) | (1 << RADIO_PCNF0_S1LEN_Pos); | 
| joshuajnoble | 0:a01a54c0dc90 | 92 | NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | | 
| joshuajnoble | 0:a01a54c0dc90 | 93 | (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | | 
| joshuajnoble | 0:a01a54c0dc90 | 94 | ((m_config_local.rf_addr_length - 1) << RADIO_PCNF1_BALEN_Pos) | | 
| joshuajnoble | 0:a01a54c0dc90 | 95 | (payload_length << RADIO_PCNF1_STATLEN_Pos) | | 
| joshuajnoble | 0:a01a54c0dc90 | 96 | (payload_length << RADIO_PCNF1_MAXLEN_Pos); | 
| joshuajnoble | 0:a01a54c0dc90 | 97 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 98 | |
| joshuajnoble | 0:a01a54c0dc90 | 99 | static void update_rf_payload_format_sb(uint32_t payload_length) | 
| joshuajnoble | 0:a01a54c0dc90 | 100 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 101 | NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S0LEN_Pos) | (0 << RADIO_PCNF0_LFLEN_Pos) | (0 << RADIO_PCNF0_S1LEN_Pos); | 
| joshuajnoble | 0:a01a54c0dc90 | 102 | NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | | 
| joshuajnoble | 0:a01a54c0dc90 | 103 | (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | | 
| joshuajnoble | 0:a01a54c0dc90 | 104 | ((m_config_local.rf_addr_length - 1) << RADIO_PCNF1_BALEN_Pos) | | 
| joshuajnoble | 0:a01a54c0dc90 | 105 | (payload_length << RADIO_PCNF1_STATLEN_Pos) | | 
| joshuajnoble | 0:a01a54c0dc90 | 106 | (payload_length << RADIO_PCNF1_MAXLEN_Pos); | 
| joshuajnoble | 0:a01a54c0dc90 | 107 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 108 | |
| joshuajnoble | 0:a01a54c0dc90 | 109 | // Function that swaps the bits within each byte in a uint32. Used to convert from nRF24L type addressing to nRF51 type addressing | 
| joshuajnoble | 0:a01a54c0dc90 | 110 | static uint32_t bytewise_bit_swap(uint32_t inp) | 
| joshuajnoble | 0:a01a54c0dc90 | 111 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 112 | inp = (inp & 0xF0F0F0F0) >> 4 | (inp & 0x0F0F0F0F) << 4; | 
| joshuajnoble | 0:a01a54c0dc90 | 113 | inp = (inp & 0xCCCCCCCC) >> 2 | (inp & 0x33333333) << 2; | 
| joshuajnoble | 0:a01a54c0dc90 | 114 | return (inp & 0xAAAAAAAA) >> 1 | (inp & 0x55555555) << 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 115 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 116 | |
| joshuajnoble | 0:a01a54c0dc90 | 117 | static void update_radio_parameters() | 
| joshuajnoble | 0:a01a54c0dc90 | 118 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 119 | // Protocol | 
| joshuajnoble | 0:a01a54c0dc90 | 120 | switch(m_config_local.protocol) | 
| joshuajnoble | 0:a01a54c0dc90 | 121 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 122 | case UESB_PROTOCOL_ESB_DPL: | 
| joshuajnoble | 0:a01a54c0dc90 | 123 | update_rf_payload_format = update_rf_payload_format_esb_dpl; | 
| joshuajnoble | 0:a01a54c0dc90 | 124 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 125 | case UESB_PROTOCOL_ESB: | 
| joshuajnoble | 0:a01a54c0dc90 | 126 | update_rf_payload_format = update_rf_payload_format_esb; | 
| joshuajnoble | 0:a01a54c0dc90 | 127 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 128 | case UESB_PROTOCOL_SB: | 
| joshuajnoble | 0:a01a54c0dc90 | 129 | update_rf_payload_format = update_rf_payload_format_sb; | 
| joshuajnoble | 0:a01a54c0dc90 | 130 | on_radio_end = (m_config_local.mode == UESB_MODE_PTX ? on_radio_end_sb_tx : on_radio_end_sb_rx); | 
| joshuajnoble | 0:a01a54c0dc90 | 131 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 132 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 133 | // TX power | 
| joshuajnoble | 0:a01a54c0dc90 | 134 | NRF_RADIO->TXPOWER = m_config_local.tx_output_power << RADIO_TXPOWER_TXPOWER_Pos; | 
| joshuajnoble | 0:a01a54c0dc90 | 135 | |
| joshuajnoble | 0:a01a54c0dc90 | 136 | // RF bitrate | 
| joshuajnoble | 0:a01a54c0dc90 | 137 | NRF_RADIO->MODE = m_config_local.bitrate << RADIO_MODE_MODE_Pos; | 
| joshuajnoble | 0:a01a54c0dc90 | 138 | switch(m_config_local.bitrate) | 
| joshuajnoble | 0:a01a54c0dc90 | 139 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 140 | case UESB_BITRATE_2MBPS: | 
| joshuajnoble | 0:a01a54c0dc90 | 141 | m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_2MBPS; | 
| joshuajnoble | 0:a01a54c0dc90 | 142 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 143 | case UESB_BITRATE_1MBPS: | 
| joshuajnoble | 0:a01a54c0dc90 | 144 | m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS; | 
| joshuajnoble | 0:a01a54c0dc90 | 145 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 146 | case UESB_BITRATE_250KBPS: | 
| joshuajnoble | 0:a01a54c0dc90 | 147 | m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_250KBPS; | 
| joshuajnoble | 0:a01a54c0dc90 | 148 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 149 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 150 | |
| joshuajnoble | 0:a01a54c0dc90 | 151 | // CRC configuration | 
| joshuajnoble | 0:a01a54c0dc90 | 152 | NRF_RADIO->CRCCNF = m_config_local.crc << RADIO_CRCCNF_LEN_Pos; | 
| joshuajnoble | 0:a01a54c0dc90 | 153 | if(m_config_local.crc == RADIO_CRCCNF_LEN_Two) | 
| joshuajnoble | 0:a01a54c0dc90 | 154 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 155 | NRF_RADIO->CRCINIT = 0xFFFFUL; // Initial value | 
| joshuajnoble | 0:a01a54c0dc90 | 156 | NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16+x^12^x^5+1 | 
| joshuajnoble | 0:a01a54c0dc90 | 157 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 158 | else if(m_config_local.crc == RADIO_CRCCNF_LEN_One) | 
| joshuajnoble | 0:a01a54c0dc90 | 159 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 160 | NRF_RADIO->CRCINIT = 0xFFUL; // Initial value | 
| joshuajnoble | 0:a01a54c0dc90 | 161 | NRF_RADIO->CRCPOLY = 0x107UL; // CRC poly: x^8+x^2^x^1+1 | 
| joshuajnoble | 0:a01a54c0dc90 | 162 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 163 | |
| joshuajnoble | 0:a01a54c0dc90 | 164 | // Packet format | 
| joshuajnoble | 0:a01a54c0dc90 | 165 | update_rf_payload_format(m_config_local.payload_length); | 
| joshuajnoble | 0:a01a54c0dc90 | 166 | |
| joshuajnoble | 0:a01a54c0dc90 | 167 | // Radio address config | 
| joshuajnoble | 0:a01a54c0dc90 | 168 | NRF_RADIO->PREFIX0 = bytewise_bit_swap(m_config_local.rx_address_p3 << 24 | m_config_local.rx_address_p2 << 16 | m_config_local.rx_address_p1[0] << 8 | m_config_local.rx_address_p0[0]); | 
| joshuajnoble | 0:a01a54c0dc90 | 169 | NRF_RADIO->PREFIX1 = bytewise_bit_swap(m_config_local.rx_address_p7 << 24 | m_config_local.rx_address_p6 << 16 | m_config_local.rx_address_p5 << 8 | m_config_local.rx_address_p4); | 
| joshuajnoble | 0:a01a54c0dc90 | 170 | NRF_RADIO->BASE0 = bytewise_bit_swap(m_config_local.rx_address_p0[1] << 24 | m_config_local.rx_address_p0[2] << 16 | m_config_local.rx_address_p0[3] << 8 | m_config_local.rx_address_p0[4]); | 
| joshuajnoble | 0:a01a54c0dc90 | 171 | NRF_RADIO->BASE1 = bytewise_bit_swap(m_config_local.rx_address_p1[1] << 24 | m_config_local.rx_address_p1[2] << 16 | m_config_local.rx_address_p1[3] << 8 | m_config_local.rx_address_p1[4]); | 
| joshuajnoble | 0:a01a54c0dc90 | 172 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 173 | |
| joshuajnoble | 0:a01a54c0dc90 | 174 | static void initialize_fifos() | 
| joshuajnoble | 0:a01a54c0dc90 | 175 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 176 | m_tx_fifo.entry_point = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 177 | m_tx_fifo.exit_point = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 178 | m_tx_fifo.count = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 179 | for(int i = 0; i < UESB_CORE_TX_FIFO_SIZE; i++) | 
| joshuajnoble | 0:a01a54c0dc90 | 180 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 181 | m_tx_fifo.payload_ptr[i] = &m_tx_fifo_payload[i]; | 
| joshuajnoble | 0:a01a54c0dc90 | 182 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 183 | |
| joshuajnoble | 0:a01a54c0dc90 | 184 | m_rx_fifo.entry_point = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 185 | m_rx_fifo.exit_point = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 186 | m_rx_fifo.count = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 187 | for(int i = 0; i < UESB_CORE_RX_FIFO_SIZE; i++) | 
| joshuajnoble | 0:a01a54c0dc90 | 188 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 189 | m_rx_fifo.payload_ptr[i] = &m_rx_fifo_payload[i]; | 
| joshuajnoble | 0:a01a54c0dc90 | 190 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 191 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 192 | |
| joshuajnoble | 0:a01a54c0dc90 | 193 | static void tx_fifo_remove_last() | 
| joshuajnoble | 0:a01a54c0dc90 | 194 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 195 | if(m_tx_fifo.count > 0) | 
| joshuajnoble | 0:a01a54c0dc90 | 196 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 197 | DISABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 198 | m_tx_fifo.count--; | 
| joshuajnoble | 0:a01a54c0dc90 | 199 | m_tx_fifo.exit_point++; | 
| joshuajnoble | 0:a01a54c0dc90 | 200 | if(m_tx_fifo.exit_point >= UESB_CORE_TX_FIFO_SIZE) m_tx_fifo.exit_point = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 201 | ENABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 202 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 203 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 204 | |
| joshuajnoble | 0:a01a54c0dc90 | 205 | static bool rx_fifo_push_rfbuf(uint8_t pipe) | 
| joshuajnoble | 0:a01a54c0dc90 | 206 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 207 | if(m_rx_fifo.count < UESB_CORE_RX_FIFO_SIZE) | 
| joshuajnoble | 0:a01a54c0dc90 | 208 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 209 | if(m_config_local.protocol == UESB_PROTOCOL_ESB_DPL) | 
| joshuajnoble | 0:a01a54c0dc90 | 210 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 211 | if(m_rx_payload_buffer[0] > UESB_CORE_MAX_PAYLOAD_LENGTH) return false; | 
| joshuajnoble | 0:a01a54c0dc90 | 212 | m_rx_fifo.payload_ptr[m_rx_fifo.entry_point]->length = m_rx_payload_buffer[0]; | 
| joshuajnoble | 0:a01a54c0dc90 | 213 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 214 | else | 
| joshuajnoble | 0:a01a54c0dc90 | 215 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 216 | m_rx_fifo.payload_ptr[m_rx_fifo.entry_point]->length = m_config_local.payload_length; | 
| joshuajnoble | 0:a01a54c0dc90 | 217 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 218 | if(m_config_local.protocol == UESB_PROTOCOL_SB) | 
| joshuajnoble | 0:a01a54c0dc90 | 219 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 220 | memcpy(m_rx_fifo.payload_ptr[m_rx_fifo.entry_point]->data, &m_rx_payload_buffer[0], m_rx_fifo.payload_ptr[m_rx_fifo.entry_point]->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 221 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 222 | else | 
| joshuajnoble | 0:a01a54c0dc90 | 223 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 224 | memcpy(m_rx_fifo.payload_ptr[m_rx_fifo.entry_point]->data, &m_rx_payload_buffer[2], m_rx_fifo.payload_ptr[m_rx_fifo.entry_point]->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 225 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 226 | m_rx_fifo.payload_ptr[m_rx_fifo.entry_point]->pipe = pipe; | 
| joshuajnoble | 0:a01a54c0dc90 | 227 | m_rx_fifo.payload_ptr[m_rx_fifo.entry_point]->rssi = NRF_RADIO->RSSISAMPLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 228 | if(++m_rx_fifo.entry_point >= UESB_CORE_RX_FIFO_SIZE) m_rx_fifo.entry_point = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 229 | m_rx_fifo.count++; | 
| joshuajnoble | 0:a01a54c0dc90 | 230 | return true; | 
| joshuajnoble | 0:a01a54c0dc90 | 231 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 232 | return false; | 
| joshuajnoble | 0:a01a54c0dc90 | 233 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 234 | |
| joshuajnoble | 0:a01a54c0dc90 | 235 | static void sys_timer_init() | 
| joshuajnoble | 0:a01a54c0dc90 | 236 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 237 | // Configure the system timer with a 1 MHz base frequency | 
| joshuajnoble | 0:a01a54c0dc90 | 238 | UESB_SYS_TIMER->PRESCALER = 4; | 
| joshuajnoble | 0:a01a54c0dc90 | 239 | UESB_SYS_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit; | 
| joshuajnoble | 0:a01a54c0dc90 | 240 | UESB_SYS_TIMER->SHORTS = TIMER_SHORTS_COMPARE1_CLEAR_Msk | TIMER_SHORTS_COMPARE1_STOP_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 241 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 242 | |
| joshuajnoble | 0:a01a54c0dc90 | 243 | static void ppi_init() | 
| joshuajnoble | 0:a01a54c0dc90 | 244 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 245 | NRF_PPI->CH[UESB_PPI_TIMER_START].EEP = (uint32_t)&NRF_RADIO->EVENTS_READY; | 
| joshuajnoble | 0:a01a54c0dc90 | 246 | NRF_PPI->CH[UESB_PPI_TIMER_START].TEP = (uint32_t)&UESB_SYS_TIMER->TASKS_START; | 
| joshuajnoble | 0:a01a54c0dc90 | 247 | NRF_PPI->CH[UESB_PPI_TIMER_STOP].EEP = (uint32_t)&NRF_RADIO->EVENTS_ADDRESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 248 | NRF_PPI->CH[UESB_PPI_TIMER_STOP].TEP = (uint32_t)&UESB_SYS_TIMER->TASKS_STOP; | 
| joshuajnoble | 0:a01a54c0dc90 | 249 | NRF_PPI->CH[UESB_PPI_RX_TIMEOUT].EEP = (uint32_t)&UESB_SYS_TIMER->EVENTS_COMPARE[0]; | 
| joshuajnoble | 0:a01a54c0dc90 | 250 | NRF_PPI->CH[UESB_PPI_RX_TIMEOUT].TEP = (uint32_t)&NRF_RADIO->TASKS_DISABLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 251 | NRF_PPI->CH[UESB_PPI_TX_START].EEP = (uint32_t)&UESB_SYS_TIMER->EVENTS_COMPARE[1]; | 
| joshuajnoble | 0:a01a54c0dc90 | 252 | NRF_PPI->CH[UESB_PPI_TX_START].TEP = (uint32_t)&NRF_RADIO->TASKS_TXEN; | 
| joshuajnoble | 0:a01a54c0dc90 | 253 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 254 | |
| joshuajnoble | 0:a01a54c0dc90 | 255 | uint32_t uesb_init(uesb_config_t *parameters) | 
| joshuajnoble | 0:a01a54c0dc90 | 256 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 257 | if(m_uesb_mainstate != UESB_STATE_UNINITIALIZED) return UESB_ERROR_ALREADY_INITIALIZED; | 
| joshuajnoble | 0:a01a54c0dc90 | 258 | m_event_handler = parameters->event_handler; | 
| joshuajnoble | 0:a01a54c0dc90 | 259 | memcpy(&m_config_local, parameters, sizeof(uesb_config_t)); | 
| joshuajnoble | 0:a01a54c0dc90 | 260 | |
| joshuajnoble | 0:a01a54c0dc90 | 261 | m_interrupt_flags = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 262 | m_pid = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 263 | m_last_rx_packet_pid = 0xFF; | 
| joshuajnoble | 0:a01a54c0dc90 | 264 | m_last_rx_packet_crc = 0xFFFFFFFF; | 
| joshuajnoble | 0:a01a54c0dc90 | 265 | |
| joshuajnoble | 0:a01a54c0dc90 | 266 | update_radio_parameters(); | 
| joshuajnoble | 0:a01a54c0dc90 | 267 | |
| joshuajnoble | 0:a01a54c0dc90 | 268 | initialize_fifos(); | 
| joshuajnoble | 0:a01a54c0dc90 | 269 | |
| joshuajnoble | 0:a01a54c0dc90 | 270 | sys_timer_init(); | 
| joshuajnoble | 0:a01a54c0dc90 | 271 | |
| joshuajnoble | 0:a01a54c0dc90 | 272 | ppi_init(); | 
| joshuajnoble | 0:a01a54c0dc90 | 273 | |
| joshuajnoble | 0:a01a54c0dc90 | 274 | NVIC_SetPriority(RADIO_IRQn, m_config_local.radio_irq_priority & 0x03); | 
| joshuajnoble | 0:a01a54c0dc90 | 275 | |
| joshuajnoble | 0:a01a54c0dc90 | 276 | //m_uesb_initialized = true; | 
| joshuajnoble | 0:a01a54c0dc90 | 277 | m_uesb_mainstate = UESB_STATE_IDLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 278 | |
| joshuajnoble | 0:a01a54c0dc90 | 279 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 280 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 281 | |
| joshuajnoble | 0:a01a54c0dc90 | 282 | uint32_t uesb_disable(void) | 
| joshuajnoble | 0:a01a54c0dc90 | 283 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 284 | if(m_uesb_mainstate != UESB_STATE_IDLE) return UESB_ERROR_NOT_IDLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 285 | NRF_PPI->CHENCLR = (1 << UESB_PPI_TIMER_START) | (1 << UESB_PPI_TIMER_STOP) | (1 << UESB_PPI_RX_TIMEOUT) | (1 << UESB_PPI_TX_START); | 
| joshuajnoble | 0:a01a54c0dc90 | 286 | m_uesb_mainstate = UESB_STATE_UNINITIALIZED; | 
| joshuajnoble | 0:a01a54c0dc90 | 287 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 288 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 289 | |
| joshuajnoble | 0:a01a54c0dc90 | 290 | static void start_tx_transaction() | 
| joshuajnoble | 0:a01a54c0dc90 | 291 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 292 | bool ack; | 
| joshuajnoble | 0:a01a54c0dc90 | 293 | m_last_tx_attempts = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 294 | // Prepare the payload | 
| joshuajnoble | 0:a01a54c0dc90 | 295 | current_payload = m_tx_fifo.payload_ptr[m_tx_fifo.exit_point]; | 
| joshuajnoble | 0:a01a54c0dc90 | 296 | m_pid = (m_pid + 1) % 4; | 
| joshuajnoble | 0:a01a54c0dc90 | 297 | switch(m_config_local.protocol) | 
| joshuajnoble | 0:a01a54c0dc90 | 298 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 299 | case UESB_PROTOCOL_SB: | 
| joshuajnoble | 0:a01a54c0dc90 | 300 | update_rf_payload_format(current_payload->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 301 | memcpy(&m_tx_payload_buffer[0], current_payload->data, current_payload->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 302 | NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 303 | NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 304 | on_radio_disabled = on_radio_disabled_esb_dpl_tx_noack; | 
| joshuajnoble | 0:a01a54c0dc90 | 305 | m_uesb_mainstate = UESB_STATE_PTX_TX; | 
| joshuajnoble | 0:a01a54c0dc90 | 306 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 307 | |
| joshuajnoble | 0:a01a54c0dc90 | 308 | case UESB_PROTOCOL_ESB: | 
| joshuajnoble | 0:a01a54c0dc90 | 309 | update_rf_payload_format(current_payload->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 310 | m_tx_payload_buffer[0] = 0xCC | m_pid; | 
| joshuajnoble | 0:a01a54c0dc90 | 311 | m_tx_payload_buffer[1] = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 312 | memcpy(&m_tx_payload_buffer[2], current_payload->data, current_payload->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 313 | |
| joshuajnoble | 0:a01a54c0dc90 | 314 | NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_RXEN_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 315 | NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk | RADIO_INTENSET_READY_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 316 | |
| joshuajnoble | 0:a01a54c0dc90 | 317 | // Configure the retransmit counter | 
| joshuajnoble | 0:a01a54c0dc90 | 318 | m_retransmits_remaining = m_config_local.retransmit_count; | 
| joshuajnoble | 0:a01a54c0dc90 | 319 | on_radio_disabled = on_radio_disabled_esb_dpl_tx; | 
| joshuajnoble | 0:a01a54c0dc90 | 320 | m_uesb_mainstate = UESB_STATE_PTX_TX_ACK; | 
| joshuajnoble | 0:a01a54c0dc90 | 321 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 322 | |
| joshuajnoble | 0:a01a54c0dc90 | 323 | case UESB_PROTOCOL_ESB_DPL: | 
| joshuajnoble | 0:a01a54c0dc90 | 324 | ack = current_payload->noack == 0 || m_config_local.dynamic_ack_enabled == 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 325 | m_tx_payload_buffer[0] = current_payload->length; | 
| joshuajnoble | 0:a01a54c0dc90 | 326 | m_tx_payload_buffer[1] = m_pid << 1 | ((current_payload->noack == 0 && m_config_local.dynamic_ack_enabled) ? 0x01 : 0x00); | 
| joshuajnoble | 0:a01a54c0dc90 | 327 | memcpy(&m_tx_payload_buffer[2], current_payload->data, current_payload->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 328 | if(ack) | 
| joshuajnoble | 0:a01a54c0dc90 | 329 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 330 | NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_RXEN_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 331 | NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk | RADIO_INTENSET_READY_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 332 | |
| joshuajnoble | 0:a01a54c0dc90 | 333 | // Configure the retransmit counter | 
| joshuajnoble | 0:a01a54c0dc90 | 334 | m_retransmits_remaining = m_config_local.retransmit_count; | 
| joshuajnoble | 0:a01a54c0dc90 | 335 | on_radio_disabled = on_radio_disabled_esb_dpl_tx; | 
| joshuajnoble | 0:a01a54c0dc90 | 336 | m_uesb_mainstate = UESB_STATE_PTX_TX_ACK; | 
| joshuajnoble | 0:a01a54c0dc90 | 337 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 338 | else | 
| joshuajnoble | 0:a01a54c0dc90 | 339 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 340 | NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON; | 
| joshuajnoble | 0:a01a54c0dc90 | 341 | NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 342 | on_radio_disabled = on_radio_disabled_esb_dpl_tx_noack; | 
| joshuajnoble | 0:a01a54c0dc90 | 343 | m_uesb_mainstate = UESB_STATE_PTX_TX; | 
| joshuajnoble | 0:a01a54c0dc90 | 344 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 345 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 346 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 347 | |
| joshuajnoble | 0:a01a54c0dc90 | 348 | NRF_RADIO->TXADDRESS = current_payload->pipe; | 
| joshuajnoble | 0:a01a54c0dc90 | 349 | NRF_RADIO->RXADDRESSES = 1 << current_payload->pipe; | 
| joshuajnoble | 0:a01a54c0dc90 | 350 | |
| joshuajnoble | 0:a01a54c0dc90 | 351 | NRF_RADIO->FREQUENCY = m_config_local.rf_channel; | 
| joshuajnoble | 0:a01a54c0dc90 | 352 | |
| joshuajnoble | 0:a01a54c0dc90 | 353 | NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer; | 
| joshuajnoble | 0:a01a54c0dc90 | 354 | |
| joshuajnoble | 0:a01a54c0dc90 | 355 | NVIC_ClearPendingIRQ(RADIO_IRQn); | 
| joshuajnoble | 0:a01a54c0dc90 | 356 | NVIC_EnableIRQ(RADIO_IRQn); | 
| joshuajnoble | 0:a01a54c0dc90 | 357 | |
| joshuajnoble | 0:a01a54c0dc90 | 358 | NRF_RADIO->EVENTS_ADDRESS = NRF_RADIO->EVENTS_PAYLOAD = NRF_RADIO->EVENTS_DISABLED = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 359 | DEBUG_PIN_SET(DEBUGPIN4); | 
| joshuajnoble | 0:a01a54c0dc90 | 360 | NRF_RADIO->TASKS_TXEN = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 361 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 362 | |
| joshuajnoble | 0:a01a54c0dc90 | 363 | static uint32_t write_tx_payload(uesb_payload_t *payload, bool noack) // ~50us @ 61 bytes SB | 
| joshuajnoble | 0:a01a54c0dc90 | 364 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 365 | if(m_uesb_mainstate == UESB_STATE_UNINITIALIZED) return UESB_ERROR_NOT_INITIALIZED; | 
| joshuajnoble | 0:a01a54c0dc90 | 366 | if(m_tx_fifo.count >= UESB_CORE_TX_FIFO_SIZE) return UESB_ERROR_TX_FIFO_FULL; | 
| joshuajnoble | 0:a01a54c0dc90 | 367 | |
| joshuajnoble | 0:a01a54c0dc90 | 368 | DISABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 369 | if(noack && m_config_local.dynamic_ack_enabled) payload->noack = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 370 | else payload->noack = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 371 | memcpy(m_tx_fifo.payload_ptr[m_tx_fifo.entry_point], payload, sizeof(uesb_payload_t)); | 
| joshuajnoble | 0:a01a54c0dc90 | 372 | m_tx_fifo.entry_point++; | 
| joshuajnoble | 0:a01a54c0dc90 | 373 | if(m_tx_fifo.entry_point >= UESB_CORE_TX_FIFO_SIZE) m_tx_fifo.entry_point = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 374 | m_tx_fifo.count++; | 
| joshuajnoble | 0:a01a54c0dc90 | 375 | ENABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 376 | |
| joshuajnoble | 0:a01a54c0dc90 | 377 | if(m_config_local.tx_mode == UESB_TXMODE_AUTO && m_uesb_mainstate == UESB_STATE_IDLE) | 
| joshuajnoble | 0:a01a54c0dc90 | 378 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 379 | start_tx_transaction(); | 
| joshuajnoble | 0:a01a54c0dc90 | 380 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 381 | |
| joshuajnoble | 0:a01a54c0dc90 | 382 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 383 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 384 | |
| joshuajnoble | 0:a01a54c0dc90 | 385 | uint32_t uesb_write_tx_payload(uesb_payload_t *payload) | 
| joshuajnoble | 0:a01a54c0dc90 | 386 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 387 | return write_tx_payload(payload, false); | 
| joshuajnoble | 0:a01a54c0dc90 | 388 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 389 | |
| joshuajnoble | 0:a01a54c0dc90 | 390 | uint32_t uesb_write_tx_payload_noack(uesb_payload_t *payload) | 
| joshuajnoble | 0:a01a54c0dc90 | 391 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 392 | if(m_config_local.dynamic_ack_enabled == 0) return UESB_ERROR_DYN_ACK_NOT_ENABLED; | 
| joshuajnoble | 0:a01a54c0dc90 | 393 | return write_tx_payload(payload, true); | 
| joshuajnoble | 0:a01a54c0dc90 | 394 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 395 | |
| joshuajnoble | 0:a01a54c0dc90 | 396 | uint32_t uesb_write_ack_payload(uesb_payload_t *payload) | 
| joshuajnoble | 0:a01a54c0dc90 | 397 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 398 | if(m_uesb_mainstate == UESB_STATE_UNINITIALIZED) return UESB_ERROR_NOT_INITIALIZED; | 
| joshuajnoble | 0:a01a54c0dc90 | 399 | if((m_uesb_mainstate != UESB_STATE_PRX) && | 
| joshuajnoble | 0:a01a54c0dc90 | 400 | (m_uesb_mainstate != UESB_STATE_PRX_SEND_ACK) && | 
| joshuajnoble | 0:a01a54c0dc90 | 401 | (m_uesb_mainstate != UESB_STATE_PRX_SEND_ACK_PAYLOAD)) | 
| joshuajnoble | 0:a01a54c0dc90 | 402 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 403 | return UESB_ERROR_NOT_IN_RX_MODE; | 
| joshuajnoble | 0:a01a54c0dc90 | 404 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 405 | if(m_tx_fifo.count >= UESB_CORE_TX_FIFO_SIZE) return UESB_ERROR_TX_FIFO_FULL; | 
| joshuajnoble | 0:a01a54c0dc90 | 406 | |
| joshuajnoble | 0:a01a54c0dc90 | 407 | DISABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 408 | memcpy(m_tx_fifo.payload_ptr[m_tx_fifo.entry_point], payload, sizeof(uesb_payload_t)); | 
| joshuajnoble | 0:a01a54c0dc90 | 409 | m_tx_fifo.entry_point++; | 
| joshuajnoble | 0:a01a54c0dc90 | 410 | if(m_tx_fifo.entry_point >= UESB_CORE_TX_FIFO_SIZE) m_tx_fifo.entry_point = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 411 | m_tx_fifo.count++; | 
| joshuajnoble | 0:a01a54c0dc90 | 412 | ENABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 413 | |
| joshuajnoble | 0:a01a54c0dc90 | 414 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 415 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 416 | |
| joshuajnoble | 0:a01a54c0dc90 | 417 | uint32_t uesb_read_rx_payload(uesb_payload_t *payload) | 
| joshuajnoble | 0:a01a54c0dc90 | 418 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 419 | if(m_uesb_mainstate == UESB_STATE_UNINITIALIZED) return UESB_ERROR_NOT_INITIALIZED; | 
| joshuajnoble | 0:a01a54c0dc90 | 420 | if(m_rx_fifo.count == 0) return UESB_ERROR_RX_FIFO_EMPTY; | 
| joshuajnoble | 0:a01a54c0dc90 | 421 | |
| joshuajnoble | 0:a01a54c0dc90 | 422 | DISABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 423 | payload->length = m_rx_fifo.payload_ptr[m_rx_fifo.exit_point]->length; | 
| joshuajnoble | 0:a01a54c0dc90 | 424 | payload->pipe = m_rx_fifo.payload_ptr[m_rx_fifo.exit_point]->pipe; | 
| joshuajnoble | 0:a01a54c0dc90 | 425 | payload->rssi = m_rx_fifo.payload_ptr[m_rx_fifo.exit_point]->rssi; | 
| joshuajnoble | 0:a01a54c0dc90 | 426 | memcpy(payload->data, m_rx_fifo.payload_ptr[m_rx_fifo.exit_point]->data, payload->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 427 | if(++m_rx_fifo.exit_point >= UESB_CORE_RX_FIFO_SIZE) m_rx_fifo.exit_point = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 428 | m_rx_fifo.count--; | 
| joshuajnoble | 0:a01a54c0dc90 | 429 | ENABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 430 | |
| joshuajnoble | 0:a01a54c0dc90 | 431 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 432 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 433 | |
| joshuajnoble | 0:a01a54c0dc90 | 434 | uint32_t uesb_start_tx() | 
| joshuajnoble | 0:a01a54c0dc90 | 435 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 436 | if(m_uesb_mainstate != UESB_STATE_IDLE) return UESB_ERROR_NOT_IDLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 437 | if(m_tx_fifo.count == 0) return UESB_ERROR_TX_FIFO_EMPTY; | 
| joshuajnoble | 0:a01a54c0dc90 | 438 | start_tx_transaction(); | 
| joshuajnoble | 0:a01a54c0dc90 | 439 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 440 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 441 | |
| joshuajnoble | 0:a01a54c0dc90 | 442 | uint32_t uesb_start_rx(void) | 
| joshuajnoble | 0:a01a54c0dc90 | 443 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 444 | if(m_uesb_mainstate != UESB_STATE_IDLE) return UESB_ERROR_NOT_IDLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 445 | |
| joshuajnoble | 0:a01a54c0dc90 | 446 | NRF_RADIO->INTENCLR = 0xFFFFFFFF; | 
| joshuajnoble | 0:a01a54c0dc90 | 447 | NRF_RADIO->EVENTS_DISABLED = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 448 | on_radio_disabled = on_radio_disabled_esb_dpl_rx; | 
| joshuajnoble | 0:a01a54c0dc90 | 449 | switch(m_config_local.protocol) | 
| joshuajnoble | 0:a01a54c0dc90 | 450 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 451 | case UESB_PROTOCOL_SB: | 
| joshuajnoble | 0:a01a54c0dc90 | 452 | NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_START_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 453 | NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 454 | m_uesb_mainstate = UESB_STATE_PRX; | 
| joshuajnoble | 0:a01a54c0dc90 | 455 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 456 | case UESB_PROTOCOL_ESB: | 
| joshuajnoble | 0:a01a54c0dc90 | 457 | NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_TXEN_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 458 | NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 459 | m_uesb_mainstate = UESB_STATE_PRX; | 
| joshuajnoble | 0:a01a54c0dc90 | 460 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 461 | case UESB_PROTOCOL_ESB_DPL: | 
| joshuajnoble | 0:a01a54c0dc90 | 462 | NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_TXEN_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 463 | NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 464 | m_uesb_mainstate = UESB_STATE_PRX; | 
| joshuajnoble | 0:a01a54c0dc90 | 465 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 466 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 467 | |
| joshuajnoble | 0:a01a54c0dc90 | 468 | NRF_RADIO->RXADDRESSES = m_config_local.rx_pipes_enabled; | 
| joshuajnoble | 0:a01a54c0dc90 | 469 | |
| joshuajnoble | 0:a01a54c0dc90 | 470 | NRF_RADIO->FREQUENCY = m_config_local.rf_channel; | 
| joshuajnoble | 0:a01a54c0dc90 | 471 | |
| joshuajnoble | 0:a01a54c0dc90 | 472 | NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; | 
| joshuajnoble | 0:a01a54c0dc90 | 473 | |
| joshuajnoble | 0:a01a54c0dc90 | 474 | NVIC_ClearPendingIRQ(RADIO_IRQn); | 
| joshuajnoble | 0:a01a54c0dc90 | 475 | NVIC_EnableIRQ(RADIO_IRQn); | 
| joshuajnoble | 0:a01a54c0dc90 | 476 | |
| joshuajnoble | 0:a01a54c0dc90 | 477 | NRF_RADIO->EVENTS_ADDRESS = NRF_RADIO->EVENTS_PAYLOAD = NRF_RADIO->EVENTS_DISABLED = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 478 | NRF_RADIO->TASKS_RXEN = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 479 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 480 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 481 | |
| joshuajnoble | 0:a01a54c0dc90 | 482 | uint32_t uesb_stop_rx(void) | 
| joshuajnoble | 0:a01a54c0dc90 | 483 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 484 | if((m_uesb_mainstate == UESB_STATE_PRX) || (m_uesb_mainstate == UESB_STATE_PRX_SEND_ACK_PAYLOAD)) | 
| joshuajnoble | 0:a01a54c0dc90 | 485 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 486 | NRF_RADIO->SHORTS = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 487 | NRF_RADIO->INTENCLR = 0xFFFFFFFF; | 
| joshuajnoble | 0:a01a54c0dc90 | 488 | on_radio_disabled = NULL; | 
| joshuajnoble | 0:a01a54c0dc90 | 489 | NRF_RADIO->EVENTS_DISABLED = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 490 | NRF_RADIO->TASKS_DISABLE = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 491 | while(NRF_RADIO->EVENTS_DISABLED == 0); | 
| joshuajnoble | 0:a01a54c0dc90 | 492 | m_uesb_mainstate = UESB_STATE_IDLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 493 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 494 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 495 | return UESB_ERROR_NOT_IN_RX_MODE; | 
| joshuajnoble | 0:a01a54c0dc90 | 496 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 497 | |
| joshuajnoble | 0:a01a54c0dc90 | 498 | uint32_t uesb_get_tx_attempts(uint32_t *attempts) | 
| joshuajnoble | 0:a01a54c0dc90 | 499 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 500 | if(m_uesb_mainstate == UESB_STATE_UNINITIALIZED) return UESB_ERROR_NOT_INITIALIZED; | 
| joshuajnoble | 0:a01a54c0dc90 | 501 | *attempts = m_last_tx_attempts; | 
| joshuajnoble | 0:a01a54c0dc90 | 502 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 503 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 504 | |
| joshuajnoble | 0:a01a54c0dc90 | 505 | uint32_t uesb_flush_tx(void) | 
| joshuajnoble | 0:a01a54c0dc90 | 506 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 507 | if(m_uesb_mainstate != UESB_STATE_IDLE) return UESB_ERROR_NOT_IDLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 508 | DISABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 509 | m_tx_fifo.count = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 510 | m_tx_fifo.entry_point = m_tx_fifo.exit_point = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 511 | ENABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 512 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 513 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 514 | |
| joshuajnoble | 0:a01a54c0dc90 | 515 | uint32_t uesb_flush_rx(void) | 
| joshuajnoble | 0:a01a54c0dc90 | 516 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 517 | DISABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 518 | m_rx_fifo.count = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 519 | m_rx_fifo.entry_point = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 520 | ENABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 521 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 522 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 523 | |
| joshuajnoble | 0:a01a54c0dc90 | 524 | uint32_t uesb_get_clear_interrupts(uint32_t *interrupts) | 
| joshuajnoble | 0:a01a54c0dc90 | 525 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 526 | DISABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 527 | *interrupts = m_interrupt_flags; | 
| joshuajnoble | 0:a01a54c0dc90 | 528 | m_interrupt_flags = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 529 | ENABLE_RF_IRQ; | 
| joshuajnoble | 0:a01a54c0dc90 | 530 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 531 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 532 | |
| joshuajnoble | 0:a01a54c0dc90 | 533 | uint32_t uesb_set_address(uesb_address_type_t address, const uint8_t *data_ptr) | 
| joshuajnoble | 0:a01a54c0dc90 | 534 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 535 | if(m_uesb_mainstate != UESB_STATE_IDLE) return UESB_ERROR_NOT_IDLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 536 | switch(address) | 
| joshuajnoble | 0:a01a54c0dc90 | 537 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 538 | case UESB_ADDRESS_PIPE0: | 
| joshuajnoble | 0:a01a54c0dc90 | 539 | memcpy(m_config_local.rx_address_p0, data_ptr, m_config_local.rf_addr_length); | 
| joshuajnoble | 0:a01a54c0dc90 | 540 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 541 | case UESB_ADDRESS_PIPE1: | 
| joshuajnoble | 0:a01a54c0dc90 | 542 | memcpy(m_config_local.rx_address_p1, data_ptr, m_config_local.rf_addr_length); | 
| joshuajnoble | 0:a01a54c0dc90 | 543 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 544 | case UESB_ADDRESS_PIPE2: | 
| joshuajnoble | 0:a01a54c0dc90 | 545 | m_config_local.rx_address_p2 = *data_ptr; | 
| joshuajnoble | 0:a01a54c0dc90 | 546 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 547 | case UESB_ADDRESS_PIPE3: | 
| joshuajnoble | 0:a01a54c0dc90 | 548 | m_config_local.rx_address_p3 = *data_ptr; | 
| joshuajnoble | 0:a01a54c0dc90 | 549 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 550 | case UESB_ADDRESS_PIPE4: | 
| joshuajnoble | 0:a01a54c0dc90 | 551 | m_config_local.rx_address_p4 = *data_ptr; | 
| joshuajnoble | 0:a01a54c0dc90 | 552 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 553 | case UESB_ADDRESS_PIPE5: | 
| joshuajnoble | 0:a01a54c0dc90 | 554 | m_config_local.rx_address_p5 = *data_ptr; | 
| joshuajnoble | 0:a01a54c0dc90 | 555 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 556 | case UESB_ADDRESS_PIPE6: | 
| joshuajnoble | 0:a01a54c0dc90 | 557 | m_config_local.rx_address_p6 = *data_ptr; | 
| joshuajnoble | 0:a01a54c0dc90 | 558 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 559 | case UESB_ADDRESS_PIPE7: | 
| joshuajnoble | 0:a01a54c0dc90 | 560 | m_config_local.rx_address_p7 = *data_ptr; | 
| joshuajnoble | 0:a01a54c0dc90 | 561 | break; | 
| joshuajnoble | 0:a01a54c0dc90 | 562 | default: | 
| joshuajnoble | 0:a01a54c0dc90 | 563 | return UESB_ERROR_INVALID_PARAMETERS; | 
| joshuajnoble | 0:a01a54c0dc90 | 564 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 565 | update_radio_parameters(); | 
| joshuajnoble | 0:a01a54c0dc90 | 566 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 567 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 568 | |
| joshuajnoble | 0:a01a54c0dc90 | 569 | uint32_t uesb_set_rf_channel(uint32_t channel) | 
| joshuajnoble | 0:a01a54c0dc90 | 570 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 571 | if(channel > 125) return UESB_ERROR_INVALID_PARAMETERS; | 
| joshuajnoble | 0:a01a54c0dc90 | 572 | m_config_local.rf_channel = channel; | 
| joshuajnoble | 0:a01a54c0dc90 | 573 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 574 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 575 | |
| joshuajnoble | 0:a01a54c0dc90 | 576 | uint32_t uesb_set_tx_power(uesb_tx_power_t tx_output_power) | 
| joshuajnoble | 0:a01a54c0dc90 | 577 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 578 | if(m_uesb_mainstate != UESB_STATE_IDLE) return UESB_ERROR_NOT_IDLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 579 | if ( m_config_local.tx_output_power == tx_output_power ) return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 580 | m_config_local.tx_output_power = tx_output_power; | 
| joshuajnoble | 0:a01a54c0dc90 | 581 | update_radio_parameters(); | 
| joshuajnoble | 0:a01a54c0dc90 | 582 | return UESB_SUCCESS; | 
| joshuajnoble | 0:a01a54c0dc90 | 583 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 584 | |
| joshuajnoble | 0:a01a54c0dc90 | 585 | void RADIO_IRQHandler() | 
| joshuajnoble | 0:a01a54c0dc90 | 586 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 587 | if(NRF_RADIO->EVENTS_READY && (NRF_RADIO->INTENSET & RADIO_INTENSET_READY_Msk)) | 
| joshuajnoble | 0:a01a54c0dc90 | 588 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 589 | NRF_RADIO->EVENTS_READY = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 590 | |
| joshuajnoble | 0:a01a54c0dc90 | 591 | DEBUG_PIN_SET(DEBUGPIN1); | 
| joshuajnoble | 0:a01a54c0dc90 | 592 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 593 | |
| joshuajnoble | 0:a01a54c0dc90 | 594 | if(NRF_RADIO->EVENTS_END && (NRF_RADIO->INTENSET & RADIO_INTENSET_END_Msk)) | 
| joshuajnoble | 0:a01a54c0dc90 | 595 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 596 | NRF_RADIO->EVENTS_END = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 597 | |
| joshuajnoble | 0:a01a54c0dc90 | 598 | DEBUG_PIN_SET(DEBUGPIN2); | 
| joshuajnoble | 0:a01a54c0dc90 | 599 | |
| joshuajnoble | 0:a01a54c0dc90 | 600 | // Call the correct on_radio_end function, depending on the current protocol state | 
| joshuajnoble | 0:a01a54c0dc90 | 601 | if(on_radio_end) | 
| joshuajnoble | 0:a01a54c0dc90 | 602 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 603 | on_radio_end(); | 
| joshuajnoble | 0:a01a54c0dc90 | 604 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 605 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 606 | |
| joshuajnoble | 0:a01a54c0dc90 | 607 | if(NRF_RADIO->EVENTS_DISABLED && (NRF_RADIO->INTENSET & RADIO_INTENSET_DISABLED_Msk)) | 
| joshuajnoble | 0:a01a54c0dc90 | 608 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 609 | NRF_RADIO->EVENTS_DISABLED = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 610 | |
| joshuajnoble | 0:a01a54c0dc90 | 611 | DEBUG_PIN_SET(DEBUGPIN3); | 
| joshuajnoble | 0:a01a54c0dc90 | 612 | |
| joshuajnoble | 0:a01a54c0dc90 | 613 | // Call the correct on_radio_disable function, depending on the current protocol state | 
| joshuajnoble | 0:a01a54c0dc90 | 614 | if(on_radio_disabled) | 
| joshuajnoble | 0:a01a54c0dc90 | 615 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 616 | on_radio_disabled(); | 
| joshuajnoble | 0:a01a54c0dc90 | 617 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 618 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 619 | |
| joshuajnoble | 0:a01a54c0dc90 | 620 | DEBUG_PIN_CLR(DEBUGPIN1); | 
| joshuajnoble | 0:a01a54c0dc90 | 621 | DEBUG_PIN_CLR(DEBUGPIN2); | 
| joshuajnoble | 0:a01a54c0dc90 | 622 | DEBUG_PIN_CLR(DEBUGPIN3); | 
| joshuajnoble | 0:a01a54c0dc90 | 623 | DEBUG_PIN_CLR(DEBUGPIN4); | 
| joshuajnoble | 0:a01a54c0dc90 | 624 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 625 | |
| joshuajnoble | 0:a01a54c0dc90 | 626 | static void on_radio_disabled_esb_dpl_tx_noack() | 
| joshuajnoble | 0:a01a54c0dc90 | 627 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 628 | m_interrupt_flags |= UESB_INT_TX_SUCCESS_MSK; | 
| joshuajnoble | 0:a01a54c0dc90 | 629 | tx_fifo_remove_last(); | 
| joshuajnoble | 0:a01a54c0dc90 | 630 | |
| joshuajnoble | 0:a01a54c0dc90 | 631 | if(m_tx_fifo.count == 0) | 
| joshuajnoble | 0:a01a54c0dc90 | 632 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 633 | m_uesb_mainstate = UESB_STATE_IDLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 634 | if(m_event_handler != 0) m_event_handler(); | 
| joshuajnoble | 0:a01a54c0dc90 | 635 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 636 | else | 
| joshuajnoble | 0:a01a54c0dc90 | 637 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 638 | if(m_event_handler != 0) m_event_handler(); | 
| joshuajnoble | 0:a01a54c0dc90 | 639 | start_tx_transaction(); | 
| joshuajnoble | 0:a01a54c0dc90 | 640 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 641 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 642 | |
| joshuajnoble | 0:a01a54c0dc90 | 643 | static void on_radio_disabled_esb_dpl_tx() | 
| joshuajnoble | 0:a01a54c0dc90 | 644 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 645 | // Remove the DISABLED -> RXEN shortcut, to make sure the radio stays disabled after the RX window | 
| joshuajnoble | 0:a01a54c0dc90 | 646 | NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON; | 
| joshuajnoble | 0:a01a54c0dc90 | 647 | |
| joshuajnoble | 0:a01a54c0dc90 | 648 | // Make sure the timer is started the next time the radio is ready, | 
| joshuajnoble | 0:a01a54c0dc90 | 649 | // and that it will disable the radio automatically if no packet is received by the time defined in m_wait_for_ack_timeout_us | 
| joshuajnoble | 0:a01a54c0dc90 | 650 | UESB_SYS_TIMER->CC[0] = m_wait_for_ack_timeout_us; | 
| joshuajnoble | 0:a01a54c0dc90 | 651 | UESB_SYS_TIMER->CC[1] = m_config_local.retransmit_delay - 130; | 
| joshuajnoble | 0:a01a54c0dc90 | 652 | UESB_SYS_TIMER->TASKS_CLEAR = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 653 | UESB_SYS_TIMER->EVENTS_COMPARE[0] = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 654 | UESB_SYS_TIMER->EVENTS_COMPARE[1] = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 655 | NRF_PPI->CHENSET = (1 << UESB_PPI_TIMER_START) | (1 << UESB_PPI_RX_TIMEOUT) | (1 << UESB_PPI_TIMER_STOP); | 
| joshuajnoble | 0:a01a54c0dc90 | 656 | NRF_PPI->CHENCLR = (1 << UESB_PPI_TX_START); | 
| joshuajnoble | 0:a01a54c0dc90 | 657 | NRF_RADIO->EVENTS_END = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 658 | if(m_config_local.protocol == UESB_PROTOCOL_ESB) | 
| joshuajnoble | 0:a01a54c0dc90 | 659 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 660 | update_rf_payload_format(0); | 
| joshuajnoble | 0:a01a54c0dc90 | 661 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 662 | NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; | 
| joshuajnoble | 0:a01a54c0dc90 | 663 | on_radio_disabled = on_radio_disabled_esb_dpl_tx_wait_for_ack; | 
| joshuajnoble | 0:a01a54c0dc90 | 664 | m_uesb_mainstate = UESB_STATE_PTX_RX_ACK; | 
| joshuajnoble | 0:a01a54c0dc90 | 665 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 666 | |
| joshuajnoble | 0:a01a54c0dc90 | 667 | static void on_radio_disabled_esb_dpl_tx_wait_for_ack() | 
| joshuajnoble | 0:a01a54c0dc90 | 668 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 669 | // This marks the completion of a TX_RX sequence (TX with ACK) | 
| joshuajnoble | 0:a01a54c0dc90 | 670 | |
| joshuajnoble | 0:a01a54c0dc90 | 671 | // Make sure the timer will not deactivate the radio if a packet is received | 
| joshuajnoble | 0:a01a54c0dc90 | 672 | NRF_PPI->CHENCLR = (1 << UESB_PPI_TIMER_START) | (1 << UESB_PPI_RX_TIMEOUT) | (1 << UESB_PPI_TIMER_STOP); | 
| joshuajnoble | 0:a01a54c0dc90 | 673 | |
| joshuajnoble | 0:a01a54c0dc90 | 674 | // If the radio has received a packet and the CRC status is OK | 
| joshuajnoble | 0:a01a54c0dc90 | 675 | if(NRF_RADIO->EVENTS_END && NRF_RADIO->CRCSTATUS != 0) | 
| joshuajnoble | 0:a01a54c0dc90 | 676 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 677 | UESB_SYS_TIMER->TASKS_STOP = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 678 | NRF_PPI->CHENCLR = (1 << UESB_PPI_TX_START); | 
| joshuajnoble | 0:a01a54c0dc90 | 679 | m_interrupt_flags |= UESB_INT_TX_SUCCESS_MSK; | 
| joshuajnoble | 0:a01a54c0dc90 | 680 | m_last_tx_attempts = m_config_local.retransmit_count - m_retransmits_remaining + 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 681 | tx_fifo_remove_last(); | 
| joshuajnoble | 0:a01a54c0dc90 | 682 | if(m_rx_payload_buffer[0] > 0) | 
| joshuajnoble | 0:a01a54c0dc90 | 683 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 684 | if(rx_fifo_push_rfbuf((uint8_t)NRF_RADIO->TXADDRESS)) | 
| joshuajnoble | 0:a01a54c0dc90 | 685 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 686 | m_interrupt_flags |= UESB_INT_RX_DR_MSK; | 
| joshuajnoble | 0:a01a54c0dc90 | 687 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 688 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 689 | |
| joshuajnoble | 0:a01a54c0dc90 | 690 | if((m_tx_fifo.count == 0) || (m_config_local.tx_mode == UESB_TXMODE_MANUAL)) | 
| joshuajnoble | 0:a01a54c0dc90 | 691 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 692 | m_uesb_mainstate = UESB_STATE_IDLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 693 | if(m_event_handler != 0) m_event_handler(); | 
| joshuajnoble | 0:a01a54c0dc90 | 694 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 695 | else | 
| joshuajnoble | 0:a01a54c0dc90 | 696 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 697 | if(m_event_handler != 0) m_event_handler(); | 
| joshuajnoble | 0:a01a54c0dc90 | 698 | start_tx_transaction(); | 
| joshuajnoble | 0:a01a54c0dc90 | 699 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 700 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 701 | else | 
| joshuajnoble | 0:a01a54c0dc90 | 702 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 703 | if(m_retransmits_remaining-- == 0) | 
| joshuajnoble | 0:a01a54c0dc90 | 704 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 705 | UESB_SYS_TIMER->TASKS_STOP = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 706 | NRF_PPI->CHENCLR = (1 << UESB_PPI_TX_START); | 
| joshuajnoble | 0:a01a54c0dc90 | 707 | // All retransmits are expended, and the TX operation is suspended | 
| joshuajnoble | 0:a01a54c0dc90 | 708 | m_last_tx_attempts = m_config_local.retransmit_count + 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 709 | m_interrupt_flags |= UESB_INT_TX_FAILED_MSK; | 
| joshuajnoble | 0:a01a54c0dc90 | 710 | |
| joshuajnoble | 0:a01a54c0dc90 | 711 | m_uesb_mainstate = UESB_STATE_IDLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 712 | if(m_event_handler != 0) m_event_handler(); | 
| joshuajnoble | 0:a01a54c0dc90 | 713 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 714 | else | 
| joshuajnoble | 0:a01a54c0dc90 | 715 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 716 | // We still have more retransmits left, and we should enter TX mode again as soon as the system timer reaches CC[1] | 
| joshuajnoble | 0:a01a54c0dc90 | 717 | NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_RXEN_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 718 | update_rf_payload_format(current_payload->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 719 | NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer; | 
| joshuajnoble | 0:a01a54c0dc90 | 720 | on_radio_disabled = on_radio_disabled_esb_dpl_tx; | 
| joshuajnoble | 0:a01a54c0dc90 | 721 | m_uesb_mainstate = UESB_STATE_PTX_TX_ACK; | 
| joshuajnoble | 0:a01a54c0dc90 | 722 | UESB_SYS_TIMER->TASKS_START = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 723 | NRF_PPI->CHENSET = (1 << UESB_PPI_TX_START); | 
| joshuajnoble | 0:a01a54c0dc90 | 724 | if(UESB_SYS_TIMER->EVENTS_COMPARE[1]) | 
| joshuajnoble | 0:a01a54c0dc90 | 725 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 726 | NRF_RADIO->TASKS_TXEN = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 727 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 728 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 729 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 730 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 731 | |
| joshuajnoble | 0:a01a54c0dc90 | 732 | static void on_radio_disabled_esb_dpl_rx(void) | 
| joshuajnoble | 0:a01a54c0dc90 | 733 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 734 | bool send_ack = false; | 
| joshuajnoble | 0:a01a54c0dc90 | 735 | bool set_rx_interrupt = false; | 
| joshuajnoble | 0:a01a54c0dc90 | 736 | if(NRF_RADIO->CRCSTATUS != 0 && m_rx_fifo.count < UESB_CORE_RX_FIFO_SIZE) | 
| joshuajnoble | 0:a01a54c0dc90 | 737 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 738 | send_ack = true; | 
| joshuajnoble | 0:a01a54c0dc90 | 739 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 740 | if(send_ack) | 
| joshuajnoble | 0:a01a54c0dc90 | 741 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 742 | NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_RXEN_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 743 | |
| joshuajnoble | 0:a01a54c0dc90 | 744 | // For a packet to be considered new (and not a retransmit) the PID or the CRC has to be different | 
| joshuajnoble | 0:a01a54c0dc90 | 745 | if(NRF_RADIO->RXCRC != m_last_rx_packet_crc || (m_rx_payload_buffer[1] >> 1) != m_last_rx_packet_pid) | 
| joshuajnoble | 0:a01a54c0dc90 | 746 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 747 | if((m_uesb_mainstate == UESB_STATE_PRX_SEND_ACK_PAYLOAD) && (m_tx_fifo.count > 0)) | 
| joshuajnoble | 0:a01a54c0dc90 | 748 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 749 | // It is assumed that the last ACK payload was recieved. | 
| joshuajnoble | 0:a01a54c0dc90 | 750 | if(++m_tx_fifo.exit_point >= UESB_CORE_RX_FIFO_SIZE) m_tx_fifo.exit_point = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 751 | m_tx_fifo.count--; | 
| joshuajnoble | 0:a01a54c0dc90 | 752 | |
| joshuajnoble | 0:a01a54c0dc90 | 753 | // ACK payloads also require TX_DS (page 40 of the 'nRF24LE1_Product_Specification_rev1_6.pdf'). | 
| joshuajnoble | 0:a01a54c0dc90 | 754 | m_interrupt_flags |= UESB_INT_TX_SUCCESS_MSK; | 
| joshuajnoble | 0:a01a54c0dc90 | 755 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 756 | |
| joshuajnoble | 0:a01a54c0dc90 | 757 | set_rx_interrupt = true; | 
| joshuajnoble | 0:a01a54c0dc90 | 758 | m_last_rx_packet_pid = m_rx_payload_buffer[1] >> 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 759 | m_last_rx_packet_crc = NRF_RADIO->RXCRC; | 
| joshuajnoble | 0:a01a54c0dc90 | 760 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 761 | |
| joshuajnoble | 0:a01a54c0dc90 | 762 | if(m_config_local.protocol == UESB_PROTOCOL_ESB_DPL) | 
| joshuajnoble | 0:a01a54c0dc90 | 763 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 764 | if(m_tx_fifo.count > 0) | 
| joshuajnoble | 0:a01a54c0dc90 | 765 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 766 | current_payload = m_tx_fifo.payload_ptr[m_tx_fifo.exit_point]; | 
| joshuajnoble | 0:a01a54c0dc90 | 767 | |
| joshuajnoble | 0:a01a54c0dc90 | 768 | update_rf_payload_format(current_payload->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 769 | m_tx_payload_buffer[0] = current_payload->length; | 
| joshuajnoble | 0:a01a54c0dc90 | 770 | memcpy(&m_tx_payload_buffer[2], current_payload->data, current_payload->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 771 | |
| joshuajnoble | 0:a01a54c0dc90 | 772 | m_uesb_mainstate = UESB_STATE_PRX_SEND_ACK_PAYLOAD; | 
| joshuajnoble | 0:a01a54c0dc90 | 773 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 774 | else | 
| joshuajnoble | 0:a01a54c0dc90 | 775 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 776 | update_rf_payload_format(0); | 
| joshuajnoble | 0:a01a54c0dc90 | 777 | m_tx_payload_buffer[0] = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 778 | |
| joshuajnoble | 0:a01a54c0dc90 | 779 | m_uesb_mainstate = UESB_STATE_PRX_SEND_ACK; | 
| joshuajnoble | 0:a01a54c0dc90 | 780 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 781 | |
| joshuajnoble | 0:a01a54c0dc90 | 782 | m_tx_payload_buffer[1] = m_rx_payload_buffer[1]; | 
| joshuajnoble | 0:a01a54c0dc90 | 783 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 784 | else if(m_config_local.protocol == UESB_PROTOCOL_ESB) | 
| joshuajnoble | 0:a01a54c0dc90 | 785 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 786 | m_tx_payload_buffer[0] = m_rx_payload_buffer[0]; | 
| joshuajnoble | 0:a01a54c0dc90 | 787 | m_tx_payload_buffer[1] = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 788 | |
| joshuajnoble | 0:a01a54c0dc90 | 789 | m_uesb_mainstate = UESB_STATE_PRX_SEND_ACK; | 
| joshuajnoble | 0:a01a54c0dc90 | 790 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 791 | |
| joshuajnoble | 0:a01a54c0dc90 | 792 | NRF_RADIO->TXADDRESS = NRF_RADIO->RXMATCH; | 
| joshuajnoble | 0:a01a54c0dc90 | 793 | NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer; | 
| joshuajnoble | 0:a01a54c0dc90 | 794 | |
| joshuajnoble | 0:a01a54c0dc90 | 795 | on_radio_disabled = on_radio_disabled_esb_dpl_rx_ack; | 
| joshuajnoble | 0:a01a54c0dc90 | 796 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 797 | else | 
| joshuajnoble | 0:a01a54c0dc90 | 798 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 799 | NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON; | 
| joshuajnoble | 0:a01a54c0dc90 | 800 | update_rf_payload_format(m_config_local.payload_length); | 
| joshuajnoble | 0:a01a54c0dc90 | 801 | NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; | 
| joshuajnoble | 0:a01a54c0dc90 | 802 | NRF_RADIO->EVENTS_DISABLED = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 803 | NRF_RADIO->TASKS_DISABLE = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 804 | while(NRF_RADIO->EVENTS_DISABLED == 0); | 
| joshuajnoble | 0:a01a54c0dc90 | 805 | NRF_RADIO->EVENTS_DISABLED = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 806 | NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_TXEN_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 807 | NRF_RADIO->TASKS_RXEN = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 808 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 809 | if(set_rx_interrupt) | 
| joshuajnoble | 0:a01a54c0dc90 | 810 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 811 | rx_fifo_push_rfbuf(NRF_RADIO->RXMATCH); | 
| joshuajnoble | 0:a01a54c0dc90 | 812 | m_interrupt_flags |= UESB_INT_RX_DR_MSK; | 
| joshuajnoble | 0:a01a54c0dc90 | 813 | if(m_event_handler != 0) m_event_handler(); | 
| joshuajnoble | 0:a01a54c0dc90 | 814 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 815 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 816 | |
| joshuajnoble | 0:a01a54c0dc90 | 817 | static void on_radio_disabled_esb_dpl_rx_ack(void) | 
| joshuajnoble | 0:a01a54c0dc90 | 818 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 819 | NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_TXEN_Msk; | 
| joshuajnoble | 0:a01a54c0dc90 | 820 | update_rf_payload_format(m_config_local.payload_length); | 
| joshuajnoble | 0:a01a54c0dc90 | 821 | NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; | 
| joshuajnoble | 0:a01a54c0dc90 | 822 | on_radio_disabled = on_radio_disabled_esb_dpl_rx; | 
| joshuajnoble | 0:a01a54c0dc90 | 823 | |
| joshuajnoble | 0:a01a54c0dc90 | 824 | if(m_uesb_mainstate == UESB_STATE_PRX_SEND_ACK) | 
| joshuajnoble | 0:a01a54c0dc90 | 825 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 826 | // In the case of UESB_STATE_PRX_SEND_ACK_PAYLOAD the state will be updated when the next packet is received. | 
| joshuajnoble | 0:a01a54c0dc90 | 827 | m_uesb_mainstate = UESB_STATE_PRX; | 
| joshuajnoble | 0:a01a54c0dc90 | 828 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 829 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 830 | |
| joshuajnoble | 0:a01a54c0dc90 | 831 | static void on_radio_end_sb_tx(void) | 
| joshuajnoble | 0:a01a54c0dc90 | 832 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 833 | m_interrupt_flags |= UESB_INT_TX_SUCCESS_MSK; | 
| joshuajnoble | 0:a01a54c0dc90 | 834 | tx_fifo_remove_last(); | 
| joshuajnoble | 0:a01a54c0dc90 | 835 | if(m_config_local.tx_mode == UESB_TXMODE_MANUAL || m_tx_fifo.count == 0) | 
| joshuajnoble | 0:a01a54c0dc90 | 836 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 837 | // No more packets to send. Disable the radio and set the state to idle. | 
| joshuajnoble | 0:a01a54c0dc90 | 838 | NRF_RADIO->EVENTS_DISABLED = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 839 | NRF_RADIO->TASKS_DISABLE = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 840 | while(!NRF_RADIO->EVENTS_DISABLED); | 
| joshuajnoble | 0:a01a54c0dc90 | 841 | NRF_RADIO->EVENTS_DISABLED = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 842 | m_uesb_mainstate = UESB_STATE_IDLE; | 
| joshuajnoble | 0:a01a54c0dc90 | 843 | if(m_event_handler != 0) m_event_handler(); | 
| joshuajnoble | 0:a01a54c0dc90 | 844 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 845 | else | 
| joshuajnoble | 0:a01a54c0dc90 | 846 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 847 | // Send another packet automatically without disabling the radio first. | 
| joshuajnoble | 0:a01a54c0dc90 | 848 | current_payload = m_tx_fifo.payload_ptr[m_tx_fifo.exit_point]; | 
| joshuajnoble | 0:a01a54c0dc90 | 849 | |
| joshuajnoble | 0:a01a54c0dc90 | 850 | update_rf_payload_format(current_payload->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 851 | memcpy(&m_tx_payload_buffer[0], current_payload->data, current_payload->length); | 
| joshuajnoble | 0:a01a54c0dc90 | 852 | |
| joshuajnoble | 0:a01a54c0dc90 | 853 | NRF_RADIO->TXADDRESS = current_payload->pipe; | 
| joshuajnoble | 0:a01a54c0dc90 | 854 | |
| joshuajnoble | 0:a01a54c0dc90 | 855 | NVIC_ClearPendingIRQ(RADIO_IRQn); | 
| joshuajnoble | 0:a01a54c0dc90 | 856 | NVIC_EnableIRQ(RADIO_IRQn); | 
| joshuajnoble | 0:a01a54c0dc90 | 857 | |
| joshuajnoble | 0:a01a54c0dc90 | 858 | NRF_RADIO->EVENTS_ADDRESS = NRF_RADIO->EVENTS_PAYLOAD = 0; | 
| joshuajnoble | 0:a01a54c0dc90 | 859 | NRF_RADIO->TASKS_START = 1; | 
| joshuajnoble | 0:a01a54c0dc90 | 860 | |
| joshuajnoble | 0:a01a54c0dc90 | 861 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 862 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 863 | |
| joshuajnoble | 0:a01a54c0dc90 | 864 | static void on_radio_end_sb_rx(void) | 
| joshuajnoble | 0:a01a54c0dc90 | 865 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 866 | if(NRF_RADIO->CRCSTATUS != 0 && rx_fifo_push_rfbuf(NRF_RADIO->RXMATCH)) | 
| joshuajnoble | 0:a01a54c0dc90 | 867 | { | 
| joshuajnoble | 0:a01a54c0dc90 | 868 | m_interrupt_flags |= UESB_INT_RX_DR_MSK; | 
| joshuajnoble | 0:a01a54c0dc90 | 869 | if(m_event_handler != 0) m_event_handler(); | 
| joshuajnoble | 0:a01a54c0dc90 | 870 | } | 
| joshuajnoble | 0:a01a54c0dc90 | 871 | } | 
