Line data Source code
1 : #include "ConvCode.h" 2 : #include <string.h> 3 : 4 : // each 32-bit word stores 8 values, one per each nibble 5 : static const uint32_t ConvCodeTable1_3[16] = { 6 : 0x07347043, 0x61521625, 0x16256152, 0x70430734, 7 : 0x43703407, 0x25165261, 0x52612516, 0x34074370, 8 : 0x70430734, 0x16256152, 0x61521625, 0x07347043, 9 : 0x34074370, 0x52612516, 0x25165261, 0x43703407, 10 : }; 11 : 12 : static const uint32_t ConvCodeTable1_2[4] = { 13 : 0x03122130, 0x21300312, 0x30211203, 0x12033021, 14 : }; 15 : 16 1 : RadioLibConvCode::RadioLibConvCode() { 17 : 18 1 : } 19 : 20 0 : void RadioLibConvCode::begin(uint8_t rt) { 21 0 : this->enc_state = 0; 22 0 : this->rate = rt; 23 0 : } 24 : 25 0 : int16_t RadioLibConvCode::encode(const uint8_t* in, size_t in_bits, uint8_t* out, size_t* out_bits) { 26 0 : if(!in || !out) { 27 0 : return(RADIOLIB_ERR_UNKNOWN); 28 : } 29 : 30 : size_t ind_bit; 31 0 : uint16_t data_out_bitcount = 0; 32 0 : uint32_t bin_out_word = 0; 33 : 34 : // iterate over the provided bits 35 0 : for(ind_bit = 0; ind_bit < in_bits; ind_bit++) { 36 0 : uint8_t cur_bit = GET_BIT_IN_ARRAY_LSB(in, ind_bit); 37 0 : const uint32_t* lut_ptr = (this->rate == 2) ? ConvCodeTable1_2 : ConvCodeTable1_3; 38 0 : uint8_t word_pos = this->enc_state / 4; 39 0 : uint8_t byte_pos = (3 - (this->enc_state % 4)) * 8; 40 0 : uint8_t nibble_pos = (1 - cur_bit) * 4; 41 0 : uint8_t g1g0 = (lut_ptr[word_pos] >> (byte_pos + nibble_pos)) & 0x0F; 42 : 43 0 : uint8_t mod = this->rate == 2 ? 16 : 64; 44 0 : this->enc_state = (this->enc_state * 2 + cur_bit) % mod; 45 0 : bin_out_word |= (g1g0 << ((7 - (ind_bit % 8)) * this->rate)); 46 0 : if(ind_bit % 8 == 7) { 47 0 : if(this->rate == 3) { 48 0 : *out++ = (uint8_t)(bin_out_word >> 16); 49 : } 50 0 : *out++ = (uint8_t)(bin_out_word >> 8); 51 0 : *out++ = (uint8_t)bin_out_word; 52 0 : bin_out_word = 0; 53 : } 54 0 : data_out_bitcount += this->rate; 55 : } 56 : 57 0 : if(ind_bit % 8) { 58 0 : if(this->rate == 3) { 59 0 : *out++ = (uint8_t)(bin_out_word >> 16); 60 : } 61 0 : *out++ = (uint8_t)(bin_out_word >> 8); 62 0 : *out++ = (uint8_t)bin_out_word; 63 : } 64 : 65 0 : if(out_bits) { *out_bits = data_out_bitcount; } 66 : 67 0 : return(RADIOLIB_ERR_NONE); 68 : }