BA / SerialCom

Fork of OmniWheels by Gustav Atmel

Committer:
gustavatmel
Date:
Tue May 01 15:47:08 2018 +0000
Revision:
1:9c5af431a1f1
sdf

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gustavatmel 1:9c5af431a1f1 1 /*
gustavatmel 1:9c5af431a1f1 2 * Copyright (c) 2017 Nordic Semiconductor ASA
gustavatmel 1:9c5af431a1f1 3 * All rights reserved.
gustavatmel 1:9c5af431a1f1 4 *
gustavatmel 1:9c5af431a1f1 5 * Redistribution and use in source and binary forms, with or without modification,
gustavatmel 1:9c5af431a1f1 6 * are permitted provided that the following conditions are met:
gustavatmel 1:9c5af431a1f1 7 *
gustavatmel 1:9c5af431a1f1 8 * 1. Redistributions of source code must retain the above copyright notice, this list
gustavatmel 1:9c5af431a1f1 9 * of conditions and the following disclaimer.
gustavatmel 1:9c5af431a1f1 10 *
gustavatmel 1:9c5af431a1f1 11 * 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
gustavatmel 1:9c5af431a1f1 12 * integrated circuit in a product or a software update for such product, must reproduce
gustavatmel 1:9c5af431a1f1 13 * the above copyright notice, this list of conditions and the following disclaimer in
gustavatmel 1:9c5af431a1f1 14 * the documentation and/or other materials provided with the distribution.
gustavatmel 1:9c5af431a1f1 15 *
gustavatmel 1:9c5af431a1f1 16 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
gustavatmel 1:9c5af431a1f1 17 * used to endorse or promote products derived from this software without specific prior
gustavatmel 1:9c5af431a1f1 18 * written permission.
gustavatmel 1:9c5af431a1f1 19 *
gustavatmel 1:9c5af431a1f1 20 * 4. This software, with or without modification, must only be used with a
gustavatmel 1:9c5af431a1f1 21 * Nordic Semiconductor ASA integrated circuit.
gustavatmel 1:9c5af431a1f1 22 *
gustavatmel 1:9c5af431a1f1 23 * 5. Any software provided in binary or object form under this license must not be reverse
gustavatmel 1:9c5af431a1f1 24 * engineered, decompiled, modified and/or disassembled.
gustavatmel 1:9c5af431a1f1 25 *
gustavatmel 1:9c5af431a1f1 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
gustavatmel 1:9c5af431a1f1 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
gustavatmel 1:9c5af431a1f1 28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
gustavatmel 1:9c5af431a1f1 29 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
gustavatmel 1:9c5af431a1f1 30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
gustavatmel 1:9c5af431a1f1 31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
gustavatmel 1:9c5af431a1f1 32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
gustavatmel 1:9c5af431a1f1 33 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
gustavatmel 1:9c5af431a1f1 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
gustavatmel 1:9c5af431a1f1 35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
gustavatmel 1:9c5af431a1f1 36 *
gustavatmel 1:9c5af431a1f1 37 */
gustavatmel 1:9c5af431a1f1 38
gustavatmel 1:9c5af431a1f1 39 #if defined(DEVICE_TRNG)
gustavatmel 1:9c5af431a1f1 40
gustavatmel 1:9c5af431a1f1 41 #include "hal/trng_api.h"
gustavatmel 1:9c5af431a1f1 42 #include "hal/lp_ticker_api.h"
gustavatmel 1:9c5af431a1f1 43
gustavatmel 1:9c5af431a1f1 44 #include "nrf_drv_rng.h"
gustavatmel 1:9c5af431a1f1 45
gustavatmel 1:9c5af431a1f1 46 #define DEFAULT_TIMEOUT_US (1000*1000)
gustavatmel 1:9c5af431a1f1 47
gustavatmel 1:9c5af431a1f1 48 /* Macro for testing if the SoftDevice is active, regardless of whether the
gustavatmel 1:9c5af431a1f1 49 * application is build with the SoftDevice or not.
gustavatmel 1:9c5af431a1f1 50 */
gustavatmel 1:9c5af431a1f1 51 #if defined(SOFTDEVICE_PRESENT)
gustavatmel 1:9c5af431a1f1 52 #include "nrf_sdm.h"
gustavatmel 1:9c5af431a1f1 53 static uint8_t wrapper(void) {
gustavatmel 1:9c5af431a1f1 54 uint8_t softdevice_is_enabled;
gustavatmel 1:9c5af431a1f1 55 ret_code_t result = sd_softdevice_is_enabled(&softdevice_is_enabled);
gustavatmel 1:9c5af431a1f1 56 return ((result == NRF_SUCCESS) && (softdevice_is_enabled == 1));
gustavatmel 1:9c5af431a1f1 57 }
gustavatmel 1:9c5af431a1f1 58 #define NRF_HAL_SD_IS_ENABLED() wrapper()
gustavatmel 1:9c5af431a1f1 59 #else
gustavatmel 1:9c5af431a1f1 60 #define NRF_HAL_SD_IS_ENABLED() 0
gustavatmel 1:9c5af431a1f1 61 #endif
gustavatmel 1:9c5af431a1f1 62
gustavatmel 1:9c5af431a1f1 63 /** Initialize the TRNG peripheral
gustavatmel 1:9c5af431a1f1 64 *
gustavatmel 1:9c5af431a1f1 65 * @param obj The TRNG object
gustavatmel 1:9c5af431a1f1 66 */
gustavatmel 1:9c5af431a1f1 67 void trng_init(trng_t *obj)
gustavatmel 1:9c5af431a1f1 68 {
gustavatmel 1:9c5af431a1f1 69 (void) obj;
gustavatmel 1:9c5af431a1f1 70
gustavatmel 1:9c5af431a1f1 71 /* Initialize low power ticker. Used for timeouts. */
gustavatmel 1:9c5af431a1f1 72 static bool first_init = true;
gustavatmel 1:9c5af431a1f1 73
gustavatmel 1:9c5af431a1f1 74 if (first_init) {
gustavatmel 1:9c5af431a1f1 75 first_init = false;
gustavatmel 1:9c5af431a1f1 76 lp_ticker_init();
gustavatmel 1:9c5af431a1f1 77 }
gustavatmel 1:9c5af431a1f1 78 }
gustavatmel 1:9c5af431a1f1 79
gustavatmel 1:9c5af431a1f1 80 /** Deinitialize the TRNG peripheral
gustavatmel 1:9c5af431a1f1 81 *
gustavatmel 1:9c5af431a1f1 82 * @param obj The TRNG object
gustavatmel 1:9c5af431a1f1 83 */
gustavatmel 1:9c5af431a1f1 84 void trng_free(trng_t *obj)
gustavatmel 1:9c5af431a1f1 85 {
gustavatmel 1:9c5af431a1f1 86 (void) obj;
gustavatmel 1:9c5af431a1f1 87 }
gustavatmel 1:9c5af431a1f1 88
gustavatmel 1:9c5af431a1f1 89 /** Get random data from TRNG peripheral
gustavatmel 1:9c5af431a1f1 90 *
gustavatmel 1:9c5af431a1f1 91 * @param obj The TRNG object
gustavatmel 1:9c5af431a1f1 92 * @param output The pointer to an output array
gustavatmel 1:9c5af431a1f1 93 * @param length The size of output data, to avoid buffer overwrite
gustavatmel 1:9c5af431a1f1 94 * @param output_length The length of generated data
gustavatmel 1:9c5af431a1f1 95 * @return 0 success, -1 fail
gustavatmel 1:9c5af431a1f1 96 */
gustavatmel 1:9c5af431a1f1 97 int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length)
gustavatmel 1:9c5af431a1f1 98 {
gustavatmel 1:9c5af431a1f1 99 (void) obj;
gustavatmel 1:9c5af431a1f1 100
gustavatmel 1:9c5af431a1f1 101 /* Use SDK RNG driver if SoftDevice is enabled. */
gustavatmel 1:9c5af431a1f1 102 if (NRF_HAL_SD_IS_ENABLED()) {
gustavatmel 1:9c5af431a1f1 103
gustavatmel 1:9c5af431a1f1 104 /* Initialize driver once. */
gustavatmel 1:9c5af431a1f1 105 static bool nordic_driver_init = true;
gustavatmel 1:9c5af431a1f1 106
gustavatmel 1:9c5af431a1f1 107 if (nordic_driver_init) {
gustavatmel 1:9c5af431a1f1 108 nordic_driver_init = false;
gustavatmel 1:9c5af431a1f1 109 nrf_drv_rng_init(NULL);
gustavatmel 1:9c5af431a1f1 110 }
gustavatmel 1:9c5af431a1f1 111
gustavatmel 1:9c5af431a1f1 112 /* Query how many bytes are available. */
gustavatmel 1:9c5af431a1f1 113 uint8_t bytes_available;
gustavatmel 1:9c5af431a1f1 114 nrf_drv_rng_bytes_available(&bytes_available);
gustavatmel 1:9c5af431a1f1 115
gustavatmel 1:9c5af431a1f1 116 /* If no bytes are cached, block until at least 1 byte is available. */
gustavatmel 1:9c5af431a1f1 117 if (bytes_available == 0) {
gustavatmel 1:9c5af431a1f1 118 nrf_drv_rng_block_rand(output, 1);
gustavatmel 1:9c5af431a1f1 119 *output_length = 1;
gustavatmel 1:9c5af431a1f1 120 } else {
gustavatmel 1:9c5af431a1f1 121
gustavatmel 1:9c5af431a1f1 122 /* Get up to the requested number of bytes. */
gustavatmel 1:9c5af431a1f1 123 if (bytes_available > length) {
gustavatmel 1:9c5af431a1f1 124 bytes_available = length;
gustavatmel 1:9c5af431a1f1 125 }
gustavatmel 1:9c5af431a1f1 126
gustavatmel 1:9c5af431a1f1 127 ret_code_t result = nrf_drv_rng_rand(output, bytes_available);
gustavatmel 1:9c5af431a1f1 128
gustavatmel 1:9c5af431a1f1 129 /* Set output length with available bytes. */
gustavatmel 1:9c5af431a1f1 130 if (result == NRF_SUCCESS) {
gustavatmel 1:9c5af431a1f1 131 *output_length = bytes_available;
gustavatmel 1:9c5af431a1f1 132 } else {
gustavatmel 1:9c5af431a1f1 133 *output_length = 0;
gustavatmel 1:9c5af431a1f1 134 }
gustavatmel 1:9c5af431a1f1 135 }
gustavatmel 1:9c5af431a1f1 136 } else {
gustavatmel 1:9c5af431a1f1 137
gustavatmel 1:9c5af431a1f1 138 /* Initialize low-level registers once. */
gustavatmel 1:9c5af431a1f1 139 static bool nordic_register_init = true;
gustavatmel 1:9c5af431a1f1 140
gustavatmel 1:9c5af431a1f1 141 if (nordic_register_init) {
gustavatmel 1:9c5af431a1f1 142 nordic_register_init = false;
gustavatmel 1:9c5af431a1f1 143
gustavatmel 1:9c5af431a1f1 144 /* Enable RNG */
gustavatmel 1:9c5af431a1f1 145 nrf_rng_error_correction_enable();
gustavatmel 1:9c5af431a1f1 146 nrf_rng_task_trigger(NRF_RNG_TASK_START);
gustavatmel 1:9c5af431a1f1 147 }
gustavatmel 1:9c5af431a1f1 148
gustavatmel 1:9c5af431a1f1 149 /* Copy out one byte at a time. */
gustavatmel 1:9c5af431a1f1 150 size_t index = 0;
gustavatmel 1:9c5af431a1f1 151 for ( ; index < length; index++) {
gustavatmel 1:9c5af431a1f1 152
gustavatmel 1:9c5af431a1f1 153 /* Setup stop watch for timeout. */
gustavatmel 1:9c5af431a1f1 154 uint32_t start_us = lp_ticker_read();
gustavatmel 1:9c5af431a1f1 155 uint32_t now_us = start_us;
gustavatmel 1:9c5af431a1f1 156
gustavatmel 1:9c5af431a1f1 157 /* Block until timeout or random numer is ready. */
gustavatmel 1:9c5af431a1f1 158 while (((now_us - start_us) < DEFAULT_TIMEOUT_US) &&
gustavatmel 1:9c5af431a1f1 159 !nrf_rng_event_get(NRF_RNG_EVENT_VALRDY)) {
gustavatmel 1:9c5af431a1f1 160 now_us = lp_ticker_read();
gustavatmel 1:9c5af431a1f1 161 }
gustavatmel 1:9c5af431a1f1 162
gustavatmel 1:9c5af431a1f1 163 /* Abort if timeout was reached. */
gustavatmel 1:9c5af431a1f1 164 if ((now_us - start_us) >= DEFAULT_TIMEOUT_US) {
gustavatmel 1:9c5af431a1f1 165 break;
gustavatmel 1:9c5af431a1f1 166 } else {
gustavatmel 1:9c5af431a1f1 167
gustavatmel 1:9c5af431a1f1 168 /* Read random byte and clear event in preparation for the next byte. */
gustavatmel 1:9c5af431a1f1 169 nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY);
gustavatmel 1:9c5af431a1f1 170 output[index] = nrf_rng_random_value_get();
gustavatmel 1:9c5af431a1f1 171 }
gustavatmel 1:9c5af431a1f1 172 }
gustavatmel 1:9c5af431a1f1 173
gustavatmel 1:9c5af431a1f1 174 /* Set output length with available bytes. */
gustavatmel 1:9c5af431a1f1 175 *output_length = index;
gustavatmel 1:9c5af431a1f1 176 }
gustavatmel 1:9c5af431a1f1 177
gustavatmel 1:9c5af431a1f1 178 /* Set return value based on how many bytes was read. */
gustavatmel 1:9c5af431a1f1 179 return (*output_length == 0) ? -1 : 0;
gustavatmel 1:9c5af431a1f1 180 }
gustavatmel 1:9c5af431a1f1 181
gustavatmel 1:9c5af431a1f1 182 #endif