From 3061ecca3d0fdfb87dabbf5f63c9e06c2a30f53a Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 23 Aug 2018 17:08:59 +0200 Subject: o Initial import. --- .../proprietary_rf/esb_low_power_ptx/main.c | 277 +++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 thirdparty/nRF5_SDK_15.0.0_a53641a/examples/proprietary_rf/esb_low_power_ptx/main.c (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/examples/proprietary_rf/esb_low_power_ptx/main.c') diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/examples/proprietary_rf/esb_low_power_ptx/main.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/examples/proprietary_rf/esb_low_power_ptx/main.c new file mode 100644 index 0000000..071d2bc --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/examples/proprietary_rf/esb_low_power_ptx/main.c @@ -0,0 +1,277 @@ +/** + * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#include "nrf_esb.h" + +#include +#include +#include +#include "sdk_common.h" +#include "nrf.h" +#include "nrf_error.h" +#include "nrf_esb_error_codes.h" +#include "nrf_delay.h" +#include "nrf_gpio.h" +#include "boards.h" +#include "app_util.h" + +#define RESET_MEMORY_TEST_BYTE (0x0DUL) /**< Known sequence written to a special register to check if this wake up is from System OFF. */ +#define RAM_RETENTION_OFF (0x00000003UL) /**< The flag used to turn off RAM retention on nRF52. */ + +#define BTN_PRESSED 0 /**< Value of a pressed button. */ +#define BTN_RELEASED 1 /**< Value of a released button. */ + +//#define NRF_ESB_LEGACY + +/*lint -save -esym(40, BUTTON_1) -esym(40, BUTTON_2) -esym(40, BUTTON_3) -esym(40, BUTTON_4) -esym(40, LED_1) -esym(40, LED_2) -esym(40, LED_3) -esym(40, LED_4) */ + +static nrf_esb_payload_t tx_payload = NRF_ESB_CREATE_PAYLOAD(0, 0x01, 0x00); +static nrf_esb_payload_t rx_payload; +static uint32_t button_state_1; +static uint32_t button_state_2; +static uint32_t button_state_3; +static uint32_t button_state_4; +static volatile bool esb_completed = false; + +void system_off( void ) +{ +#ifdef NRF51 + NRF_POWER->RAMON |= (POWER_RAMON_OFFRAM0_RAM0Off << POWER_RAMON_OFFRAM0_Pos) | + (POWER_RAMON_OFFRAM1_RAM1Off << POWER_RAMON_OFFRAM1_Pos); +#endif //NRF51 +#ifdef NRF52 + NRF_POWER->RAM[0].POWER = RAM_RETENTION_OFF; + NRF_POWER->RAM[1].POWER = RAM_RETENTION_OFF; + NRF_POWER->RAM[2].POWER = RAM_RETENTION_OFF; + NRF_POWER->RAM[3].POWER = RAM_RETENTION_OFF; + NRF_POWER->RAM[4].POWER = RAM_RETENTION_OFF; + NRF_POWER->RAM[5].POWER = RAM_RETENTION_OFF; + NRF_POWER->RAM[6].POWER = RAM_RETENTION_OFF; + NRF_POWER->RAM[7].POWER = RAM_RETENTION_OFF; +#endif //NRF52 + + // Turn off LEDs before sleeping to conserve energy. + bsp_board_leds_off(); + + // Set nRF5 into System OFF. Reading out value and looping after setting the register + // to guarantee System OFF in nRF52. + NRF_POWER->SYSTEMOFF = 0x1; + (void) NRF_POWER->SYSTEMOFF; + while (true); +} + + +void nrf_esb_event_handler(nrf_esb_evt_t const * p_event) +{ + switch (p_event->evt_id) + { + case NRF_ESB_EVENT_TX_SUCCESS: + break; + case NRF_ESB_EVENT_TX_FAILED: + (void) nrf_esb_flush_tx(); + break; + case NRF_ESB_EVENT_RX_RECEIVED: + // Get the most recent element from the RX FIFO. + while (nrf_esb_read_rx_payload(&rx_payload) == NRF_SUCCESS) ; + + // For each LED, set it as indicated in the rx_payload, but invert it for the button + // which is pressed. This is because the ack payload from the PRX is reflecting the + // state from before receiving the packet. + nrf_gpio_pin_write(LED_1, !( ((rx_payload.data[0] & 0x01) == 0) ^ (button_state_1 == BTN_PRESSED)) ); + nrf_gpio_pin_write(LED_2, !( ((rx_payload.data[0] & 0x02) == 0) ^ (button_state_2 == BTN_PRESSED)) ); + nrf_gpio_pin_write(LED_3, !( ((rx_payload.data[0] & 0x04) == 0) ^ (button_state_3 == BTN_PRESSED)) ); + nrf_gpio_pin_write(LED_4, !( ((rx_payload.data[0] & 0x08) == 0) ^ (button_state_4 == BTN_PRESSED)) ); + break; + } + + esb_completed = true; +} + + +void clocks_start( void ) +{ + // Start HFCLK and wait for it to start. + NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; + NRF_CLOCK->TASKS_HFCLKSTART = 1; + while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); +} + + +uint32_t esb_init( void ) +{ + uint32_t err_code; + uint8_t base_addr_0[4] = {0xE7, 0xE7, 0xE7, 0xE7}; + uint8_t base_addr_1[4] = {0xC2, 0xC2, 0xC2, 0xC2}; + uint8_t addr_prefix[8] = {0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8 }; + +#ifndef NRF_ESB_LEGACY + nrf_esb_config_t nrf_esb_config = NRF_ESB_DEFAULT_CONFIG; +#else // NRF_ESB_LEGACY + nrf_esb_config_t nrf_esb_config = NRF_ESB_LEGACY_CONFIG; +#endif // NRF_ESB_LEGACY + nrf_esb_config.retransmit_count = 6; + nrf_esb_config.selective_auto_ack = false; + nrf_esb_config.protocol = NRF_ESB_PROTOCOL_ESB_DPL; + nrf_esb_config.bitrate = NRF_ESB_BITRATE_2MBPS; + nrf_esb_config.event_handler = nrf_esb_event_handler; + nrf_esb_config.mode = NRF_ESB_MODE_PTX; + + err_code = nrf_esb_init(&nrf_esb_config); + VERIFY_SUCCESS(err_code); + + err_code = nrf_esb_set_base_address_0(base_addr_0); + VERIFY_SUCCESS(err_code); + + err_code = nrf_esb_set_base_address_1(base_addr_1); + VERIFY_SUCCESS(err_code); + + err_code = nrf_esb_set_prefixes(addr_prefix, 8); + VERIFY_SUCCESS(err_code); + + tx_payload.length = 3; + tx_payload.pipe = 0; + tx_payload.data[0] = 0x00; + + return NRF_SUCCESS; +} + + +uint32_t gpio_check_and_esb_tx() +{ + uint32_t err_code; + button_state_1 = nrf_gpio_pin_read(BUTTON_1); + button_state_2 = nrf_gpio_pin_read(BUTTON_2); + button_state_3 = nrf_gpio_pin_read(BUTTON_3); + button_state_4 = nrf_gpio_pin_read(BUTTON_4); + if (button_state_1 == BTN_PRESSED) + { + tx_payload.data[0] |= 1 << 0; + } + if (button_state_2 == BTN_PRESSED) + { + tx_payload.data[0] |= 1 << 1; + } + if (button_state_3 == BTN_PRESSED) + { + tx_payload.data[0] |= 1 << 2; + } + if (button_state_4 == BTN_PRESSED) + { + tx_payload.data[0] |= 1 << 3; + } + if (button_state_1 + button_state_2 + button_state_3 + button_state_4 == BTN_PRESSED + 3 * BTN_RELEASED) + { + tx_payload.noack = false; + err_code = nrf_esb_write_payload(&tx_payload); + VERIFY_SUCCESS(err_code); + } + else + { + esb_completed = true; + } + + return NRF_SUCCESS; +} + + +void gpio_init( void ) +{ + nrf_gpio_cfg_sense_input(BUTTON_1, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); + nrf_gpio_cfg_sense_input(BUTTON_2, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); + nrf_gpio_cfg_sense_input(BUTTON_3, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); + nrf_gpio_cfg_sense_input(BUTTON_4, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); + + // Workaround for PAN_028 rev1.1 anomaly 22 - System: Issues with disable System OFF mechanism + nrf_delay_ms(1); + + bsp_board_init(BSP_INIT_LEDS); +} + + +void recover_state() +{ + uint32_t loop_count = 0; + if ((NRF_POWER->GPREGRET >> 4) == RESET_MEMORY_TEST_BYTE) + { + // Take the loop_count value. + loop_count = (uint8_t)(NRF_POWER->GPREGRET & 0xFUL); + NRF_POWER->GPREGRET = 0; + } + + loop_count++; + NRF_POWER->GPREGRET = ( (RESET_MEMORY_TEST_BYTE << 4) | loop_count); + + tx_payload.data[1] = loop_count << 4; +} + + +int main(void) +{ + uint32_t err_code; + // Initialize + clocks_start(); + err_code = esb_init(); + APP_ERROR_CHECK(err_code); + + gpio_init(); + + // Recover state if the device was woken from System OFF. + recover_state(); + + // Check state of all buttons and send an esb packet with the button press if there is exactly one. + err_code = gpio_check_and_esb_tx(); + APP_ERROR_CHECK(err_code); + + while (true) + { + // Wait for esb completed and all buttons released before going to system off. + if (esb_completed) + { + if (nrf_gpio_pin_read(BUTTON_1) == BTN_RELEASED && + nrf_gpio_pin_read(BUTTON_2) == BTN_RELEASED && + nrf_gpio_pin_read(BUTTON_3) == BTN_RELEASED && + nrf_gpio_pin_read(BUTTON_4) == BTN_RELEASED + ) + { + system_off(); + } + } + } +} +/*lint -restore */ -- cgit v1.2.3