Line data Source code
1 : /*------------------------------------------------------------------------------ 2 : -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW), 3 : -- This file is a part of the LFR FSW 4 : -- Copyright (C) 2021, Plasma Physics Laboratory - CNRS 5 : -- 6 : -- This program is free software; you can redistribute it and/or modify 7 : -- it under the terms of the GNU General Public License as published by 8 : -- the Free Software Foundation; either version 2 of the License, or 9 : -- (at your option) any later version. 10 : -- 11 : -- This program is distributed in the hope that it will be useful, 12 : -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : -- GNU General Public License for more details. 15 : -- 16 : -- You should have received a copy of the GNU General Public License 17 : -- along with this program; if not, write to the Free Software 18 : -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : -------------------------------------------------------------------------------*/ 20 : /*-- Author : Alexis Jeandet 21 : -- Contact : Alexis Jeandet 22 : -- Mail : alexis.jeandet@lpp.polytechnique.fr 23 : ----------------------------------------------------------------------------*/ 24 : #pragma once 25 : #include <stdint.h> 26 : #ifdef LFR_BIG_ENDIAN 27 : 28 : typedef union 29 : { 30 : uint16_t value; 31 : struct __attribute__((__packed__)) 32 : { 33 : uint16_t MSB : 8; 34 : uint16_t LSB : 8; 35 : } str; 36 : } str_uint16_t; 37 : 38 : typedef union 39 : { 40 : uint16_t value; 41 : struct __attribute__((__packed__)) 42 : { 43 : uint16_t exponent : 6; 44 : uint16_t mantissa : 10; 45 : } str; 46 : } float_6_10_t; 47 : 48 : typedef union 49 : { 50 : uint16_t value; 51 : struct __attribute__((__packed__)) 52 : { 53 : uint16_t sign : 1; 54 : uint16_t arg : 1; 55 : uint16_t exponent : 6; 56 : uint16_t mantissa : 8; 57 : } str; 58 : } float_1_1_6_8_t; 59 : 60 : typedef union 61 : { 62 : float value; 63 : struct __attribute__((__packed__)) 64 : { 65 : uint32_t sign : 1; 66 : uint32_t exponent : 8; 67 : uint32_t mantissa : 23; 68 : } str; 69 : } str_float_t; 70 : #endif 71 : #ifdef LFR_LITTLE_ENDIAN 72 : typedef union 73 : { 74 : uint16_t value; 75 : struct __attribute__((__packed__)) 76 : { 77 : uint16_t LSB : 8; 78 : uint16_t MSB : 8; 79 : } str; 80 : } str_uint16_t; 81 : 82 : typedef union 83 : { 84 : uint16_t value; 85 : struct __attribute__((__packed__)) 86 : { 87 : uint16_t mantissa : 10; 88 : uint16_t exponent : 6; 89 : } str; 90 : } float_6_10_t; 91 : 92 : typedef union 93 : { 94 : uint16_t value; 95 : struct __attribute__((__packed__)) 96 : { 97 : uint16_t mantissa : 8; 98 : uint16_t exponent : 6; 99 : uint16_t arg : 1; 100 : uint16_t sign : 1; 101 : } str; 102 : } float_1_1_6_8_t; 103 : 104 : typedef union 105 : { 106 : float value; 107 : struct __attribute__((__packed__)) 108 : { 109 : uint32_t mantissa : 23; 110 : uint32_t exponent : 8; 111 : uint32_t sign : 1; 112 : } str; 113 : } str_float_t; 114 : #endif 115 : 116 : typedef struct 117 : { 118 : float real; 119 : uint8_t arg; 120 : } compressed_complex; 121 : 122 : inline uint16_t to_custom_float_6_10(const float value) __attribute__((always_inline)); 123 0 : uint16_t to_custom_float_6_10(const float value) 124 : { 125 5808 : float_6_10_t result = { .value = 0 }; 126 5808 : str_float_t v = { .value = value }; 127 : 128 5808 : if ((v.str.exponent - 127) < -27) 129 : { 130 0 : return 0; 131 : } 132 5808 : if ((v.str.exponent - 127) > 36) 133 : { 134 0 : return 0xFFFF; 135 : } 136 : 137 5808 : result.str.exponent = v.str.exponent - 127 + 27; 138 5808 : result.str.mantissa = v.str.mantissa >> 13; 139 : 140 5808 : return result.value; 141 : } 142 : 143 : inline uint16_t to_custom_float_1_1_6_8(const compressed_complex value) __attribute__((always_inline)); 144 0 : uint16_t to_custom_float_1_1_6_8(const compressed_complex value) 145 : { 146 4008 : float_1_1_6_8_t result = { .value = 0 }; 147 4008 : str_float_t v_re = { .value = value.real }; 148 : 149 4008 : if ((v_re.str.exponent - 127) < -27) 150 : { 151 0 : result.str.exponent = 0; 152 0 : result.str.mantissa = 0; 153 : } 154 4008 : else if ((v_re.str.exponent - 127) > 36) 155 : { 156 0 : result.str.exponent = 0x3F; 157 0 : result.str.mantissa = 0xFF; 158 : } 159 : else { 160 4008 : result.str.exponent = v_re.str.exponent - 127 + 27; 161 4008 : result.str.mantissa = v_re.str.mantissa >> 15; 162 : } 163 : 164 4008 : result.str.sign = v_re.str.sign; 165 4008 : result.str.arg = value.arg; 166 4008 : return result.value; 167 : }