[FL-1800] IRDA: enc/decoder refactoring, Add NEC42 (#705)
* WIP: IRDA: multilen protocol refactoring, NEC42 * IRDA: Refactoring encoder/decoder Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									4768177cf5
								
							
						
					
					
						commit
						4f233ff0a3
					
				| @ -129,10 +129,7 @@ static void run_encoder_decoder(const IrdaMessage input_messages[], uint32_t inp | |||||||
|         for(int i = 0; i < timings_len; ++i) { |         for(int i = 0; i < timings_len; ++i) { | ||||||
|             message_decoded = irda_decode(decoder_handler, level, timings[i]); |             message_decoded = irda_decode(decoder_handler, level, timings[i]); | ||||||
|             if((i == timings_len - 2) && level && message_decoded) { |             if((i == timings_len - 2) && level && message_decoded) { | ||||||
|                 /* In case we end with space timing - message can be decoded at last mark.
 |                 /* In case we end with space timing - message can be decoded at last mark */ | ||||||
|                  * Exception - SIRC protocol, which has variable message length (12/15/20), |  | ||||||
|                  * and decoder recognizes protocol by silence time before next message |  | ||||||
|                  * or by timeout (irda_check_decoder_ready()). */ |  | ||||||
|                 break; |                 break; | ||||||
|             } else if(i < timings_len - 1) { |             } else if(i < timings_len - 1) { | ||||||
|                 mu_check(!message_decoded); |                 mu_check(!message_decoded); | ||||||
| @ -225,17 +222,16 @@ MU_TEST(test_mix) { | |||||||
|     RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1); |     RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1); | ||||||
|     RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); |     RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); | ||||||
|     RUN_DECODER(test_decoder_sirc_input5, test_decoder_sirc_expected5); |     RUN_DECODER(test_decoder_sirc_input5, test_decoder_sirc_expected5); | ||||||
|  |     RUN_DECODER(test_decoder_nec_input3, test_decoder_nec_expected3); | ||||||
|     RUN_DECODER(test_decoder_rc5_input5, test_decoder_rc5_expected5); |     RUN_DECODER(test_decoder_rc5_input5, test_decoder_rc5_expected5); | ||||||
|     RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1); |     RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1); | ||||||
|     RUN_DECODER(test_decoder_sirc_input3, test_decoder_sirc_expected3); |     RUN_DECODER(test_decoder_sirc_input3, test_decoder_sirc_expected3); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MU_TEST(test_decoder_nec1) { | MU_TEST(test_decoder_nec) { | ||||||
|     RUN_DECODER(test_decoder_nec_input1, test_decoder_nec_expected1); |     RUN_DECODER(test_decoder_nec_input1, test_decoder_nec_expected1); | ||||||
| } |  | ||||||
| 
 |  | ||||||
| MU_TEST(test_decoder_nec2) { |  | ||||||
|     RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2); |     RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2); | ||||||
|  |     RUN_DECODER(test_decoder_nec_input3, test_decoder_nec_expected3); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MU_TEST(test_decoder_unexpected_end_in_sequence) { | MU_TEST(test_decoder_unexpected_end_in_sequence) { | ||||||
| @ -295,6 +291,8 @@ MU_TEST(test_encoder_rc6) { | |||||||
| MU_TEST(test_encoder_decoder_all) { | MU_TEST(test_encoder_decoder_all) { | ||||||
|     RUN_ENCODER_DECODER(test_nec); |     RUN_ENCODER_DECODER(test_nec); | ||||||
|     RUN_ENCODER_DECODER(test_necext); |     RUN_ENCODER_DECODER(test_necext); | ||||||
|  |     RUN_ENCODER_DECODER(test_nec42); | ||||||
|  |     RUN_ENCODER_DECODER(test_nec42ext); | ||||||
|     RUN_ENCODER_DECODER(test_samsung32); |     RUN_ENCODER_DECODER(test_samsung32); | ||||||
|     RUN_ENCODER_DECODER(test_rc6); |     RUN_ENCODER_DECODER(test_rc6); | ||||||
|     RUN_ENCODER_DECODER(test_rc5); |     RUN_ENCODER_DECODER(test_rc5); | ||||||
| @ -312,8 +310,7 @@ MU_TEST_SUITE(test_irda_decoder_encoder) { | |||||||
|     MU_RUN_TEST(test_decoder_rc6); |     MU_RUN_TEST(test_decoder_rc6); | ||||||
|     MU_RUN_TEST(test_encoder_rc6); |     MU_RUN_TEST(test_encoder_rc6); | ||||||
|     MU_RUN_TEST(test_decoder_unexpected_end_in_sequence); |     MU_RUN_TEST(test_decoder_unexpected_end_in_sequence); | ||||||
|     MU_RUN_TEST(test_decoder_nec1); |     MU_RUN_TEST(test_decoder_nec); | ||||||
|     MU_RUN_TEST(test_decoder_nec2); |  | ||||||
|     MU_RUN_TEST(test_decoder_samsung32); |     MU_RUN_TEST(test_decoder_samsung32); | ||||||
|     MU_RUN_TEST(test_decoder_necext1); |     MU_RUN_TEST(test_decoder_necext1); | ||||||
|     MU_RUN_TEST(test_mix); |     MU_RUN_TEST(test_mix); | ||||||
|  | |||||||
| @ -178,6 +178,45 @@ const IrdaMessage test_decoder_nec_expected2[] = { | |||||||
|     {IrdaProtocolNEC,     0x00,      0x0A,   true}, |     {IrdaProtocolNEC,     0x00,      0x0A,   true}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | const uint32_t test_decoder_nec_input3[] = { | ||||||
|  | 200000,         8862, 4452, 562, 563, 559, 1681, 563, 1646, 567, 586, 556, 569, 563, 583, 559, 571, 561, 1675, 559, 565, 567, 1673, 561, 561, 561, 592, 561, 565, 567, 579, 563, 567, 565, 584, 558, 1652, 561, 592, 561, 561, 561, 1679, 565, 560, 562, 584, 558, 1659, 564, 585, 557, 566, 566, 1675, 559, 1649, 564, 589, 564, 1649, 564, 1668, 566, 565, 567, 1669, 565, | ||||||
|  |     43470,      8896, 4432, 561, 561, 561, 1679, 565, 1648, 565, 581, 561, 568, 564, 586, 567, 558, 564, 1676, 558, 564, 558, 1681, 563, 563, 559, 587, 566, 565, 567, 582, 561, 564, 558, 595, 558, 1650, 563, 590, 563, 563, 559, 1674, 560, 570, 562, 587, 566, 1645, 568, 586, 556, 565, 567, 1672, 562, 1651, 562, 584, 558, 1658, 566, 1671, 563, 561, 561, 1679, 565, | ||||||
|  | 200000,         8881, 4383, 569, 549, 573, 548, 574, 541, 571, 550, 572, 547, 575, 539, 573, 551, 571, 1651, 573, 545, 567, 554, 568, 548, 574, 1652, 572, 547, 575, 1645, 568, 1661, 573, 545, 567, 1657, 567, 554, 568, 547, 575, 1652, 572, 547, 575, 539, 573, 1657, 567, 550, 572, 545, 577, 1651, 573, 1648, 576, 545, 567, 1659, 575, 1645, 568, 555, 567, 1657, 567, | ||||||
|  |     38995,      8883, 4369, 573, 543, 569, 552, 570, 549, 573, 541, 571, 553, 569, 548, 574, 543, 569, 1658, 566, 550, 572, 548, 574, 546, 566, 1653, 571, 553, 569, 1654, 570, 1654, 570, 551, 571, 1651, 573, 547, 575, 545, 567, 1653, 571, 552, 570, 547, 575, 1649, 564, 556, 566, 550, 572, 1655, 569, 1656, 568, 546, 566, 1664, 570, 1653, 571, 547, 565, 1663, 571, | ||||||
|  | 200000,         8987, 4504, 561, 593, 539, 589, 533, 596, 515, 586, 536, 592, 540, 588, 534, 595, 517, 1713, 541, 1664, 570, 1686, 558, 596, 515, 587, 535, 593, 539, 1691, 543, 1689, 565, 588, 513, 1691, 563, 1668, 617, 1613, 641, 1615, 567, 587, 535, 593, 519, 610, 512, 590, 542, 1714, 510, 593, 539, 1691, 563, 591, 510, 1720, 535, 594, 518, 584, 538, 591, 541, | ||||||
|  |     39546,      8990, 4501, 565, 590, 542, 586, 536, 593, 508, 593, 539, 589, 543, 585, 537, 592, 509, 1720, 545, 1660, 615, 1642, 561, 567, 534, 594, 538, 590, 542, 1688, 535, 1696, 558, 595, 517, 1687, 567, 1664, 621, 1635, 619, 1611, 561, 594, 538, 590, 511, 617, 515, 586, 536, 1721, 513, 589, 543, 1687, 568, 587, 514, 1691, 563, 590, 511, 591, 541, 587, 535, | ||||||
|  | 200000,         8986, 4505, 560, 594, 538, 590, 542, 586, 515, 586, 536, 593, 539, 589, 533, 595, 517, 1714, 540, 587, 535, 594, 518, 1713, 542, 586, 515, 587, 535, 1722, 543, 1662, 562, 592, 540, 1664, 570, 585, 537, 591, 541, 1689, 545, 584, 538, 590, 542, 1688, 536, 593, 539, 589, 512, 590, 542, 586, 536, 1720, 514, 588, 544, 585, 537, 591, 541, 587, 514, | ||||||
|  |     40671,      8986, 4505, 560, 594, 538, 590, 542, 586, 515, 587, 535, 593, 539, 589, 533, 595, 516, 1714, 541, 587, 535, 594, 518, 1712, 542, 586, 515, 587, 535, 1722, 543, 1662, 561, 592, 540, 1664, 570, 585, 537, 591, 541, 1689, 545, 584, 538, 590, 542, 1688, 536, 593, 539, 589, 512, 590, 542, 586, 536, 1720, 514, 588, 544, 585, 537, 591, 541, 587, 514, | ||||||
|  | 200000,         8990, 4500, 566, 1692, 562, 1668, 566, 588, 534, 594, 518, 584, 538, 591, 541, 587, 535, 1669, 565, 589, 543, 1688, 536, 592, 540, 1691, 563, 1667, 567, 1664, 621, 1635, 568, 586, 515, 587, 535, 593, 539, 589, 543, 1662, 562, 592, 540, 588, 534, 594, 518, 585, 537, 591, 541, 587, 514, 587, 535, 594, 538, 590, 542, 586, 515, 586, 536, 593, 539, | ||||||
|  |     39544,      8993, 4498, 567, 1690, 564, 1666, 568, 586, 536, 593, 508, 593, 539, 589, 543, 585, 537, 1668, 566, 588, 544, 1687, 537, 591, 541, 1690, 564, 1666, 568, 1663, 561, 1696, 569, 585, 516, 586, 536, 593, 539, 589, 543, 1661, 562, 592, 540, 588, 534, 594, 517, 584, 538, 591, 541, 587, 514, 587, 535, 593, 539, 589, 543, 585, 516, 586, 536, 592, 540, | ||||||
|  | 200000,         8894, 4456, 589, 1676, 589, 571, 582, 574, 589, 571, 582, 1683, 582, 1677, 588, 1682, 583, 574, 589, 568, 585, 1682, 583, 1678, 587, 1680, 585, 574, 589, 565, 588, 575, 588, 1675, 590, 567, 586, 1681, 584, 571, 582, 1685, 590, 568, 585, 569, 584, 1685, 590, 567, 586, 1678, 587, 574, 589, 1672, 582, 578, 585, 1679, 586, 1674, 591, 572, 591, 1672, 582, | ||||||
|  |     39632,      8912, 4464, 560, 1703, 562, 598, 565, 594, 559, 594, 559, 1711, 564, 1698, 567, 1697, 568, 593, 560, 595, 568, 1698, 567, 1698, 567, 1693, 561, 602, 561, 596, 567, 590, 563, 1704, 561, 594, 559, 1707, 568, 591, 562, 1697, 568, 596, 567, 590, 563, 1700, 565, 596, 567, 1693, 561, 599, 564, 1701, 564, 589, 564, 1706, 559, 1704, 561, 597, 566, 1700, 565, | ||||||
|  | 200000,         9018, 4500, 565, 1666, 568, 1689, 565, 588, 513, 1691, 615, 1616, 618, 1639, 564, 1667, 567, 587, 535, 594, 538, 563, 538, 590, 542, 586, 536, 593, 508, 593, 539, 589, 543, 1688, 535, 592, 540, 588, 544, 585, 537, 591, 510, 1694, 560, 1670, 564, 1693, 562, 1669, 565, 1692, 542, 1689, 565, 588, 534, 595, 517, 585, 537, 591, 541, 587, 535, 568, 544, 584, 538, 591, 541, 1663, 560, 1696, 569, 1662, 562, 1695, 539, 1692, 614, 1616, 566, 1691, 563, 1667, 567, | ||||||
|  |     23184,      9012, 4505, 560, 1697, 537, 1693, 561, 593, 508, 1696, 569, 1662, 562, 1695, 560, 1671, 563, 591, 541, 587, 535, 594, 518, 584, 538, 590, 542, 586, 515, 613, 509, 593, 539, 1692, 542, 585, 537, 592, 540, 588, 534, 594, 518, 1687, 567, 1663, 560, 1697, 568, 1662, 562, 1695, 539, 1692, 563, 591, 541, 587, 514, 588, 544, 584, 538, 590, 542, 586, 515, 587, 535, 593, 539, 1666, 568, 1689, 565, 1665, 569, 1688, 536, 1695, 570, 1661, 562, 1694, 561, 1670, 564, | ||||||
|  | 200000,         8835, 4446, 537, 562, 539, 562, 539, 1663, 540, 1667, 536, 1669, 534, 560, 531, 573, 539, 559, 532, 1672, 531, 570, 531, 564, 537, 563, 538, 561, 540, 1660, 533, 1677, 536, 561, 540, 557, 534, 567, 534, 1668, 535, 1672, 531, 1675, 538, 555, 536, 1674, 539, 1665, 538, 1666, 537, 1671, 532, 563, 538, 1669, 534, 566, 535, 558, 533, 1677, 536, 562, 539, 558, 533, 568, 533, 1668, 535, 566, 535, 1670, 533, 1667, 536, 568, 533, 1671, 532, 1672, 531, 1676, 537, | ||||||
|  |     22779,      8870, 4437, 535, | ||||||
|  |     92592,      8861, 4414, 538, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const IrdaMessage test_decoder_nec_expected3[] = { | ||||||
|  |     {IrdaProtocolNECext,    0x286,      0xB649,     false}, | ||||||
|  |     {IrdaProtocolNECext,    0x286,      0xB649,     false}, | ||||||
|  |     {IrdaProtocolNECext,    0x6880,     0xB649,     false}, | ||||||
|  |     {IrdaProtocolNECext,    0x6880,     0xB649,     false}, | ||||||
|  |     {IrdaProtocolNECext,    0x6380,     0x150F,     false}, | ||||||
|  |     {IrdaProtocolNECext,    0x6380,     0x150F,     false}, | ||||||
|  |     {IrdaProtocolNECext,    0x6480,     0x849,      false}, | ||||||
|  |     {IrdaProtocolNECext,    0x6480,     0x849,      false}, | ||||||
|  |     {IrdaProtocolNECext,    0x7A83,     0x8,        false}, | ||||||
|  |     {IrdaProtocolNECext,    0x7A83,     0x8,        false}, | ||||||
|  |     {IrdaProtocolNEC,       0x71,       0x4A,       false}, | ||||||
|  |     {IrdaProtocolNEC,       0x71,       0x4A,       false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x7B,       0x0,        false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x7B,       0x0,        false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x11C,      0x12,       false}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| const IrdaMessage test_nec[] = { | const IrdaMessage test_nec[] = { | ||||||
|     {IrdaProtocolNEC,     0x00,      0x00,  false}, |     {IrdaProtocolNEC,     0x00,      0x00,  false}, | ||||||
|     {IrdaProtocolNEC,     0x01,      0x00,  false}, |     {IrdaProtocolNEC,     0x01,      0x00,  false}, | ||||||
| @ -209,4 +248,61 @@ const IrdaMessage test_nec[] = { | |||||||
|     {IrdaProtocolNEC,     0x55,      0x55,  true}, |     {IrdaProtocolNEC,     0x55,      0x55,  true}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | const IrdaMessage test_nec42[] = { | ||||||
|  |     {IrdaProtocolNEC42,     0x0000,      0x00,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0001,      0x00,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0001,      0x80,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0000,      0x80,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0000,      0x00,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0000,      0x00,  true}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0000,      0x00,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0000,      0x00,  true}, | ||||||
|  |     {IrdaProtocolNEC42,     0x1FFF,      0xFF,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x1FFE,      0xFF,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x1FFE,      0x7F,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x1FFF,      0x7F,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x1FFF,      0xFF,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x1FFF,      0xFF,  true}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0AAA,      0x55,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x1555,      0xAA,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x1555,      0x55,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0AAA,      0xAA,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0AAA,      0xAA,  true}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0AAA,      0xAA,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0AAA,      0xAA,  true}, | ||||||
|  |     {IrdaProtocolNEC42,     0x0AAA,      0xAA,  true}, | ||||||
|  |     {IrdaProtocolNEC42,     0x1555,      0x55,  false}, | ||||||
|  |     {IrdaProtocolNEC42,     0x1555,      0x55,  true}, | ||||||
|  |     {IrdaProtocolNEC42,     0x1555,      0x55,  true}, | ||||||
|  |     {IrdaProtocolNEC42,     0x1555,      0x55,  true}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const IrdaMessage test_nec42ext[] = { | ||||||
|  |     {IrdaProtocolNEC42ext,     0x0000000,      0x0000,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x0000001,      0x0000,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x0000001,      0x8000,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x0000000,      0x8000,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x0000000,      0x0000,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x0000000,      0x0000,  true}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x0000000,      0x0000,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x0000000,      0x0000,  true}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x3F000FF,      0xF00F,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x3F000FE,      0xF00F,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x3F000FE,      0x700F,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x3F000FF,      0x700F,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x3F000FF,      0xF00F,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x3F000FF,      0xF00F,  true}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x2AAAAAA,      0x5555,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x1555555,      0xAAAA,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x1555555,      0x5555,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x2AAAAAA,      0xAAAA,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x2AAAAAA,      0xAAAA,  true}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x2AAAAAA,      0xAAAA,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x2AAAAAA,      0xAAAA,  true}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x2AAAAAA,      0xAAAA,  true}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x1555555,      0x5555,  false}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x1555555,      0x5555,  true}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x1555555,      0x5555,  true}, | ||||||
|  |     {IrdaProtocolNEC42ext,     0x1555555,      0x5555,  true}, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -111,147 +111,145 @@ const uint32_t test_decoder_necext_input1[] = { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const IrdaMessage test_decoder_necext_expected1[] = { | const IrdaMessage test_decoder_necext_expected1[] = { | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  false}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  false}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
|     {IrdaProtocolNECext,     0x7984,    0x12,  true}, |     {IrdaProtocolNECext,     0x7984,    0xed12,  true}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| const IrdaMessage test_necext[] = { | const IrdaMessage test_necext[] = { | ||||||
|     {IrdaProtocolNECext,     0x0000,      0x00,  false}, |     {IrdaProtocolNECext,     0x0000,      0x0000,  false}, | ||||||
|     {IrdaProtocolNECext,     0x0001,      0x00,  false}, |     {IrdaProtocolNECext,     0x0001,      0x0000,  false}, | ||||||
|     {IrdaProtocolNECext,     0x0001,      0x80,  false}, |     {IrdaProtocolNECext,     0x0001,      0x8000,  false}, | ||||||
|     {IrdaProtocolNECext,     0x0000,      0x80,  false}, |     {IrdaProtocolNECext,     0x0000,      0x8000,  false}, | ||||||
|     {IrdaProtocolNECext,     0x0000,      0x00,  false}, |     {IrdaProtocolNECext,     0x0000,      0x0000,  false}, | ||||||
|     {IrdaProtocolNECext,     0x0000,      0x00,  true}, |     {IrdaProtocolNECext,     0x0000,      0x0000,  true}, | ||||||
|     {IrdaProtocolNECext,     0x0000,      0x00,  false}, |     {IrdaProtocolNECext,     0x0000,      0x0000,  false}, | ||||||
|     {IrdaProtocolNECext,     0x0000,      0x00,  true}, |     {IrdaProtocolNECext,     0x0000,      0x0000,  true}, | ||||||
|     {IrdaProtocolNECext,     0xFFFF,      0xFF,  false}, |     {IrdaProtocolNECext,     0xFFFF,      0xFFFF,  false}, | ||||||
|     {IrdaProtocolNECext,     0xFFFE,      0xFF,  false}, |     {IrdaProtocolNECext,     0xFFFE,      0xFFFF,  false}, | ||||||
|     {IrdaProtocolNECext,     0xFFFE,      0x7F,  false}, |     {IrdaProtocolNECext,     0xFFFE,      0x7FFF,  false}, | ||||||
|     {IrdaProtocolNECext,     0xFFFF,      0x7F,  false}, |     {IrdaProtocolNECext,     0xFFFF,      0x7FFF,  false}, | ||||||
|     {IrdaProtocolNECext,     0xFFFF,      0xFF,  false}, |     {IrdaProtocolNECext,     0xFFFF,      0xFFFF,  false}, | ||||||
|     {IrdaProtocolNECext,     0xFFFF,      0xFF,  true}, |     {IrdaProtocolNECext,     0xFFFF,      0xFFFF,  true}, | ||||||
|     {IrdaProtocolNECext,     0xAAAA,      0x55,  false}, |     {IrdaProtocolNECext,     0xAAAA,      0x5555,  false}, | ||||||
|     {IrdaProtocolNECext,     0x5555,      0xAA,  false}, |     {IrdaProtocolNECext,     0x5555,      0xAAAA,  false}, | ||||||
|     {IrdaProtocolNECext,     0x5555,      0x55,  false}, |     {IrdaProtocolNECext,     0x5555,      0x5555,  false}, | ||||||
|     {IrdaProtocolNECext,     0xAAAA,      0xAA,  false}, |     {IrdaProtocolNECext,     0xAAAA,      0xAAAA,  false}, | ||||||
|     {IrdaProtocolNECext,     0xAAAA,      0xAA,  true}, |     {IrdaProtocolNECext,     0xAAAA,      0xAAAA,  true}, | ||||||
| 
 | 
 | ||||||
|     {IrdaProtocolNECext,     0xAAAA,      0xAA,  false}, |     {IrdaProtocolNECext,     0xAAAA,      0xAAAA,  false}, | ||||||
|     {IrdaProtocolNECext,     0xAAAA,      0xAA,  true}, |     {IrdaProtocolNECext,     0xAAAA,      0xAAAA,  true}, | ||||||
|     {IrdaProtocolNECext,     0xAAAA,      0xAA,  true}, |     {IrdaProtocolNECext,     0xAAAA,      0xAAAA,  true}, | ||||||
| 
 | 
 | ||||||
|     {IrdaProtocolNECext,     0x5555,      0x55,  false}, |     {IrdaProtocolNECext,     0x5555,      0x5555,  false}, | ||||||
|     {IrdaProtocolNECext,     0x5555,      0x55,  true}, |     {IrdaProtocolNECext,     0x5555,      0x5555,  true}, | ||||||
|     {IrdaProtocolNECext,     0x5555,      0x55,  true}, |     {IrdaProtocolNECext,     0x5555,      0x5555,  true}, | ||||||
|     {IrdaProtocolNECext,     0x5555,      0x55,  true}, |     {IrdaProtocolNECext,     0x5555,      0x5555,  true}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -426,20 +426,14 @@ const IrdaMessage test_decoder_sirc_expected5[] = { | |||||||
|     {IrdaProtocolSIRC20, 0xFB5, 0x53, false}, |     {IrdaProtocolSIRC20, 0xFB5, 0x53, false}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| const IrdaMessage test_encoder_sirc_input1[] = { | const IrdaMessage test_encoder_sirc_input1[] = { | ||||||
|     {IrdaProtocolSIRC, 0xA, 0x55, false}, |     {IrdaProtocolSIRC, 0xA, 0x55, false}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const uint32_t test_encoder_sirc_expected1[] = { | const uint32_t test_encoder_sirc_expected1[] = { | ||||||
| 10000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, | 10000, 2400, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 600, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| const IrdaMessage test_encoder_sirc_input2[] = { | const IrdaMessage test_encoder_sirc_input2[] = { | ||||||
|     {IrdaProtocolSIRC15, 0x7D, 0x53, false}, |     {IrdaProtocolSIRC15, 0x7D, 0x53, false}, | ||||||
|     {IrdaProtocolSIRC15, 0x7D, 0x53, true}, |     {IrdaProtocolSIRC15, 0x7D, 0x53, true}, | ||||||
| @ -447,9 +441,9 @@ const IrdaMessage test_encoder_sirc_input2[] = { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const uint32_t test_encoder_sirc_expected2[] = { | const uint32_t test_encoder_sirc_expected2[] = { | ||||||
|     10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, 600, /* 2 low levels in row */ |     10000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, | ||||||
|     18000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, 600, /* 2 low levels in row */ |     18600, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, | ||||||
|     18000, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, 600, |     18600, 2400, 600, 1200, 600, 1200, 600, 600, 600, 600, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 600, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 1200, 600, 600, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const IrdaMessage test_sirc[] = { | const IrdaMessage test_sirc[] = { | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| #include "furi/check.h" | #include "furi/check.h" | ||||||
|  | #include "furi/common_defines.h" | ||||||
| #include "irda.h" | #include "irda.h" | ||||||
| #include "irda_common_i.h" | #include "irda_common_i.h" | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| @ -39,12 +40,13 @@ static bool irda_check_preamble(IrdaCommonDecoder* decoder) { | |||||||
|     bool result = false; |     bool result = false; | ||||||
|     bool start_level = (decoder->level + decoder->timings_cnt + 1) % 2; |     bool start_level = (decoder->level + decoder->timings_cnt + 1) % 2; | ||||||
| 
 | 
 | ||||||
|  |     if (decoder->timings_cnt == 0) | ||||||
|  |         return false; | ||||||
|  | 
 | ||||||
|     // align to start at Mark timing
 |     // align to start at Mark timing
 | ||||||
|     if (!start_level) { |     if (!start_level) { | ||||||
|         if (decoder->timings_cnt > 0) { |  | ||||||
|         decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 1); |         decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 1); | ||||||
|     } |     } | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     if (decoder->protocol->timings.preamble_mark == 0) { |     if (decoder->protocol->timings.preamble_mark == 0) { | ||||||
|         return true; |         return true; | ||||||
| @ -66,45 +68,75 @@ static bool irda_check_preamble(IrdaCommonDecoder* decoder) { | |||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Pulse Distance Modulation */ | 
 | ||||||
| IrdaStatus irda_common_decode_pdm(IrdaCommonDecoder* decoder) { | /**
 | ||||||
|  |  * decoder->protocol->databit_len[0] contains biggest amount of bits, for this protocol. | ||||||
|  |  * decoder->protocol->databit_len[1...] contains lesser values, but which can be decoded | ||||||
|  |  * for some protocol modifications. | ||||||
|  |  */ | ||||||
|  | static IrdaStatus irda_common_decode_bits(IrdaCommonDecoder* decoder) { | ||||||
|     furi_assert(decoder); |     furi_assert(decoder); | ||||||
| 
 | 
 | ||||||
|     uint32_t* timings = decoder->timings; |     IrdaStatus status = IrdaStatusOk; | ||||||
|     IrdaStatus status = IrdaStatusError; |     const IrdaTimings* timings = &decoder->protocol->timings; | ||||||
|  | 
 | ||||||
|  |     while (decoder->timings_cnt && (status == IrdaStatusOk)) { | ||||||
|  |         bool level = (decoder->level + decoder->timings_cnt + 1) % 2; | ||||||
|  |         uint32_t timing = decoder->timings[0]; | ||||||
|  | 
 | ||||||
|  |         /* check if short protocol version can be decoded */ | ||||||
|  |         if (timings->min_split_time && !level && (timing > timings->min_split_time)) { | ||||||
|  |             for (int i = 1; decoder->protocol->databit_len[i] && (i < COUNT_OF(decoder->protocol->databit_len)); ++i) { | ||||||
|  |                 if (decoder->protocol->databit_len[i] == decoder->databit_cnt) { | ||||||
|  |                     return IrdaStatusReady; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         status = decoder->protocol->decode(decoder, level, timing); | ||||||
|  |         furi_assert(status == IrdaStatusError || status == IrdaStatusOk); | ||||||
|  |         if (status == IrdaStatusError) { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 1); | ||||||
|  | 
 | ||||||
|  |         /* check if largest protocol version can be decoded */ | ||||||
|  |         if (level && (decoder->protocol->databit_len[0] == decoder->databit_cnt)) { | ||||||
|  |             status = IrdaStatusReady; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return status; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Pulse Distance-Width Modulation */ | ||||||
|  | IrdaStatus irda_common_decode_pdwm(IrdaCommonDecoder* decoder, bool level, uint32_t timing) { | ||||||
|  |     furi_assert(decoder); | ||||||
|  | 
 | ||||||
|  |     IrdaStatus status = IrdaStatusOk; | ||||||
|     uint32_t bit_tolerance = decoder->protocol->timings.bit_tolerance; |     uint32_t bit_tolerance = decoder->protocol->timings.bit_tolerance; | ||||||
|     uint16_t bit1_mark = decoder->protocol->timings.bit1_mark; |     uint16_t bit1_mark = decoder->protocol->timings.bit1_mark; | ||||||
|     uint16_t bit1_space = decoder->protocol->timings.bit1_space; |     uint16_t bit1_space = decoder->protocol->timings.bit1_space; | ||||||
|     uint16_t bit0_mark = decoder->protocol->timings.bit0_mark; |     uint16_t bit0_mark = decoder->protocol->timings.bit0_mark; | ||||||
|     uint16_t bit0_space = decoder->protocol->timings.bit0_space; |     uint16_t bit0_space = decoder->protocol->timings.bit0_space; | ||||||
| 
 | 
 | ||||||
|     while (1) { |     bool analyze_timing = level ^ (bit1_mark == bit0_mark); | ||||||
|         // Stop bit
 |     uint16_t bit1 = level ? bit1_mark : bit1_space; | ||||||
|         if ((decoder->databit_cnt == decoder->protocol->databit_len) && (decoder->timings_cnt == 1)) { |     uint16_t bit0 = level ? bit0_mark : bit0_space; | ||||||
|             if (MATCH_TIMING(timings[0], bit1_mark, bit_tolerance)) { |     uint16_t no_info_timing = (bit1_mark == bit0_mark) ? bit1_mark : bit1_space; | ||||||
|                 decoder->timings_cnt = 0; |  | ||||||
|                 status = IrdaStatusReady; |  | ||||||
|             } else { |  | ||||||
|                 status = IrdaStatusError; |  | ||||||
|             } |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         if (decoder->timings_cnt >= 2) { |     if (analyze_timing) { | ||||||
|             if (MATCH_TIMING(timings[0], bit1_mark, bit_tolerance) |         if (MATCH_TIMING(timing, bit1, bit_tolerance)) { | ||||||
|                 && MATCH_TIMING(timings[1], bit1_space, bit_tolerance)) { |  | ||||||
|             accumulate_lsb(decoder, 1); |             accumulate_lsb(decoder, 1); | ||||||
|             } else if (MATCH_TIMING(timings[0], bit0_mark, bit_tolerance) |         } else if (MATCH_TIMING(timing, bit0, bit_tolerance)) { | ||||||
|                 && MATCH_TIMING(timings[1], bit0_space, bit_tolerance)) { |  | ||||||
|             accumulate_lsb(decoder, 0); |             accumulate_lsb(decoder, 0); | ||||||
|         } else { |         } else { | ||||||
|             status = IrdaStatusError; |             status = IrdaStatusError; | ||||||
|                 break; |  | ||||||
|         } |         } | ||||||
|             decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 2); |  | ||||||
|     } else { |     } else { | ||||||
|             status = IrdaStatusOk; |         if (!MATCH_TIMING(timing, no_info_timing, bit_tolerance)) { | ||||||
|             break; |             status = IrdaStatusError; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -112,14 +144,11 @@ IrdaStatus irda_common_decode_pdm(IrdaCommonDecoder* decoder) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* level switch detection goes in middle of time-quant */ | /* level switch detection goes in middle of time-quant */ | ||||||
| IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder) { | IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder, bool level, uint32_t timing) { | ||||||
|     furi_assert(decoder); |     furi_assert(decoder); | ||||||
|     IrdaStatus status = IrdaStatusOk; |  | ||||||
|     uint16_t bit = decoder->protocol->timings.bit1_mark; |     uint16_t bit = decoder->protocol->timings.bit1_mark; | ||||||
|     uint16_t tolerance = decoder->protocol->timings.bit_tolerance; |     uint16_t tolerance = decoder->protocol->timings.bit_tolerance; | ||||||
| 
 | 
 | ||||||
|     while (decoder->timings_cnt) { |  | ||||||
|         uint32_t timing = decoder->timings[0]; |  | ||||||
|     bool* switch_detect = &decoder->switch_detect; |     bool* switch_detect = &decoder->switch_detect; | ||||||
|     furi_assert((*switch_detect == true) || (*switch_detect == false)); |     furi_assert((*switch_detect == true) || (*switch_detect == false)); | ||||||
| 
 | 
 | ||||||
| @ -127,96 +156,47 @@ IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder) { | |||||||
|     bool double_timing = MATCH_TIMING(timing, 2*bit, tolerance); |     bool double_timing = MATCH_TIMING(timing, 2*bit, tolerance); | ||||||
| 
 | 
 | ||||||
|     if(!single_timing && !double_timing) { |     if(!single_timing && !double_timing) { | ||||||
|             status = IrdaStatusError; |         return IrdaStatusError; | ||||||
|             break; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|         if ((decoder->protocol->manchester_start_from_space) && (decoder->databit_cnt == 0)) { |     if (decoder->protocol->manchester_start_from_space && (decoder->databit_cnt == 0)) { | ||||||
|         *switch_detect = 1; /* fake as we were previously in the middle of time-quant */ |         *switch_detect = 1; /* fake as we were previously in the middle of time-quant */ | ||||||
|             decoder->data[0] = 0;   /* first captured timing should be Mark */ |         accumulate_lsb(decoder, 0); | ||||||
|             ++decoder->databit_cnt; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (*switch_detect == 0) { |     if (*switch_detect == 0) { | ||||||
|         if (double_timing) { |         if (double_timing) { | ||||||
|                 status = IrdaStatusError; |             return IrdaStatusError; | ||||||
|                 break; |  | ||||||
|         } |         } | ||||||
|         /* only single timing - level switch required in the middle of time-quant */ |         /* only single timing - level switch required in the middle of time-quant */ | ||||||
|         *switch_detect = 1; |         *switch_detect = 1; | ||||||
|     } else { |     } else { | ||||||
|             /* double timing means we in the middle of time-quant again */ |         /* double timing means we're in the middle of time-quant again */ | ||||||
|         if (single_timing) |         if (single_timing) | ||||||
|             *switch_detect = 0; |             *switch_detect = 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|         decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 1); |  | ||||||
|         status = IrdaStatusOk; |  | ||||||
|         bool level = (decoder->level + decoder->timings_cnt) % 2; |  | ||||||
| 
 |  | ||||||
|         if (decoder->databit_cnt < decoder->protocol->databit_len) { |  | ||||||
|     if (*switch_detect) { |     if (*switch_detect) { | ||||||
|         accumulate_lsb(decoder, level); |         accumulate_lsb(decoder, level); | ||||||
|     } |     } | ||||||
|             if (decoder->databit_cnt == decoder->protocol->databit_len) { | 
 | ||||||
|                 if (level) { |     return IrdaStatusOk; | ||||||
|                     status = IrdaStatusReady; |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | IrdaMessage* irda_common_decoder_check_ready(IrdaCommonDecoder* decoder) { | ||||||
|  |     IrdaMessage* message = NULL; | ||||||
|  | 
 | ||||||
|  |     if (decoder->protocol->interpret(decoder)) { | ||||||
|  |         decoder->databit_cnt = 0; | ||||||
|  |         message = &decoder->message; | ||||||
|  |         if (decoder->protocol->decode_repeat) { | ||||||
|  |             decoder->state = IrdaCommonDecoderStateProcessRepeat; | ||||||
|         } else { |         } else { | ||||||
|             furi_assert(level); |             decoder->state = IrdaCommonDecoderStateWaitPreamble; | ||||||
|             /* cover case: sequence should be stopped after last bit was received */ |  | ||||||
|             if (single_timing) { |  | ||||||
|                 status = IrdaStatusReady; |  | ||||||
|                 break; |  | ||||||
|             } else { |  | ||||||
|                 status = IrdaStatusError; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return status; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Pulse Width Modulation */ |  | ||||||
| IrdaStatus irda_common_decode_pwm(IrdaCommonDecoder* decoder) { |  | ||||||
|     furi_assert(decoder); |  | ||||||
| 
 |  | ||||||
|     uint32_t* timings = decoder->timings; |  | ||||||
|     IrdaStatus status = IrdaStatusOk; |  | ||||||
|     uint32_t bit_tolerance = decoder->protocol->timings.bit_tolerance; |  | ||||||
|     uint16_t bit1_mark = decoder->protocol->timings.bit1_mark; |  | ||||||
|     uint16_t bit1_space = decoder->protocol->timings.bit1_space; |  | ||||||
|     uint16_t bit0_mark = decoder->protocol->timings.bit0_mark; |  | ||||||
| 
 |  | ||||||
|     while (decoder->timings_cnt) { |  | ||||||
|         bool level = (decoder->level + decoder->timings_cnt + 1) % 2; |  | ||||||
| 
 |  | ||||||
|         if (level) { |  | ||||||
|             if (MATCH_TIMING(timings[0], bit1_mark, bit_tolerance)) { |  | ||||||
|                 accumulate_lsb(decoder, 1); |  | ||||||
|             } else if (MATCH_TIMING(timings[0], bit0_mark, bit_tolerance)) { |  | ||||||
|                 accumulate_lsb(decoder, 0); |  | ||||||
|             } else { |  | ||||||
|                 status = IrdaStatusError; |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             if (!MATCH_TIMING(timings[0], bit1_space, bit_tolerance)) { |  | ||||||
|                 status = IrdaStatusError; |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 1); |  | ||||||
| 
 |  | ||||||
|         if (decoder->databit_cnt == decoder->protocol->databit_len) { |  | ||||||
|             status = IrdaStatusReady; |  | ||||||
|             break; |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return status; |     return message; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| IrdaMessage* irda_common_decode(IrdaCommonDecoder* decoder, bool level, uint32_t duration) { | IrdaMessage* irda_common_decode(IrdaCommonDecoder* decoder, bool level, uint32_t duration) { | ||||||
| @ -245,12 +225,13 @@ IrdaMessage* irda_common_decode(IrdaCommonDecoder* decoder, bool level, uint32_t | |||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|         case IrdaCommonDecoderStateDecode: |         case IrdaCommonDecoderStateDecode: | ||||||
|             status = decoder->protocol->decode(decoder); |             status = irda_common_decode_bits(decoder); | ||||||
|             if (status == IrdaStatusReady) { |             if (status == IrdaStatusReady) { | ||||||
|                 if (decoder->protocol->interpret(decoder)) { |                 message = irda_common_decoder_check_ready(decoder); | ||||||
|                     message = &decoder->message; |                 if (message) { | ||||||
|                     decoder->state = IrdaCommonDecoderStateProcessRepeat; |                     continue; | ||||||
|                 } else { |                 } else if (decoder->protocol->databit_len[0] == decoder->databit_cnt) { | ||||||
|  |                     /* error: can't decode largest protocol - begin decoding from start */ | ||||||
|                     decoder->state = IrdaCommonDecoderStateWaitPreamble; |                     decoder->state = IrdaCommonDecoderStateWaitPreamble; | ||||||
|                 } |                 } | ||||||
|             } else if (status == IrdaStatusError) { |             } else if (status == IrdaStatusError) { | ||||||
| @ -259,10 +240,6 @@ IrdaMessage* irda_common_decode(IrdaCommonDecoder* decoder, bool level, uint32_t | |||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|         case IrdaCommonDecoderStateProcessRepeat: |         case IrdaCommonDecoderStateProcessRepeat: | ||||||
|             if (!decoder->protocol->decode_repeat) { |  | ||||||
|                 decoder->state = IrdaCommonDecoderStateWaitPreamble; |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|             status = decoder->protocol->decode_repeat(decoder); |             status = decoder->protocol->decode_repeat(decoder); | ||||||
|             if (status == IrdaStatusError) { |             if (status == IrdaStatusError) { | ||||||
|                 irda_common_decoder_reset_state(decoder); |                 irda_common_decoder_reset_state(decoder); | ||||||
| @ -282,9 +259,14 @@ IrdaMessage* irda_common_decode(IrdaCommonDecoder* decoder, bool level, uint32_t | |||||||
| void* irda_common_decoder_alloc(const IrdaCommonProtocolSpec* protocol) { | void* irda_common_decoder_alloc(const IrdaCommonProtocolSpec* protocol) { | ||||||
|     furi_assert(protocol); |     furi_assert(protocol); | ||||||
| 
 | 
 | ||||||
|  |     /* protocol->databit_len[0] has to contain biggest value of bits that can be decoded */ | ||||||
|  |     for (int i = 1; i < COUNT_OF(protocol->databit_len); ++i) { | ||||||
|  |         furi_assert(protocol->databit_len[i] <= protocol->databit_len[0]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     uint32_t alloc_size = sizeof(IrdaCommonDecoder) |     uint32_t alloc_size = sizeof(IrdaCommonDecoder) | ||||||
|                           + protocol->databit_len / 8 |                           + protocol->databit_len[0] / 8 | ||||||
|                           + !!(protocol->databit_len % 8); |                           + !!(protocol->databit_len[0] % 8); | ||||||
|     IrdaCommonDecoder* decoder = furi_alloc(alloc_size); |     IrdaCommonDecoder* decoder = furi_alloc(alloc_size); | ||||||
|     memset(decoder, 0, alloc_size); |     memset(decoder, 0, alloc_size); | ||||||
|     decoder->protocol = protocol; |     decoder->protocol = protocol; | ||||||
|  | |||||||
| @ -4,6 +4,19 @@ | |||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include "irda_i.h" | #include "irda_i.h" | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | static IrdaStatus irda_common_encode_bits(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { | ||||||
|  |     IrdaStatus status = encoder->protocol->encode(encoder, duration, level); | ||||||
|  |     furi_assert(status == IrdaStatusOk); | ||||||
|  |     ++encoder->timings_encoded; | ||||||
|  |     encoder->timings_sum += *duration; | ||||||
|  |     if ((encoder->bits_encoded == encoder->bits_to_encode) && *level) { | ||||||
|  |         status = IrdaStatusDone; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return status; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * |  * | ||||||
| @ -32,14 +45,12 @@ IrdaStatus irda_common_encode_manchester(IrdaCommonEncoder* encoder, uint32_t* d | |||||||
| 
 | 
 | ||||||
|     *level = even_timing ^ logic_value; |     *level = even_timing ^ logic_value; | ||||||
|     *duration = timings->bit1_mark; |     *duration = timings->bit1_mark; | ||||||
|     if (even_timing)        /* start encoding from space */ |     if (even_timing) | ||||||
|         ++encoder->bits_encoded; |         ++encoder->bits_encoded; | ||||||
|     ++encoder->timings_encoded; |     else if (*level && (encoder->bits_encoded + 1 == encoder->bits_to_encode)) | ||||||
|     encoder->timings_sum += *duration; |         ++encoder->bits_encoded;        /* don't encode last space */ | ||||||
| 
 | 
 | ||||||
|     bool finish = (encoder->bits_encoded == encoder->protocol->databit_len); |     return IrdaStatusOk; | ||||||
|     finish |= (encoder->bits_encoded == (encoder->protocol->databit_len-1)) && *level && !even_timing; |  | ||||||
|     return finish ? IrdaStatusDone : IrdaStatusOk; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| IrdaStatus irda_common_encode_pdwm(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { | IrdaStatus irda_common_encode_pdwm(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { | ||||||
| @ -47,39 +58,25 @@ IrdaStatus irda_common_encode_pdwm(IrdaCommonEncoder* encoder, uint32_t* duratio | |||||||
|     furi_assert(duration); |     furi_assert(duration); | ||||||
|     furi_assert(level); |     furi_assert(level); | ||||||
| 
 | 
 | ||||||
|     bool done = false; |  | ||||||
|     const IrdaTimings* timings = &encoder->protocol->timings; |     const IrdaTimings* timings = &encoder->protocol->timings; | ||||||
|     uint8_t index = encoder->bits_encoded / 8; |     uint8_t index = encoder->bits_encoded / 8; | ||||||
|     uint8_t shift = encoder->bits_encoded % 8;   // LSB first
 |     uint8_t shift = encoder->bits_encoded % 8;   // LSB first
 | ||||||
|     bool logic_value = !!(encoder->data[index] & (0x01 << shift)); |     bool logic_value = !!(encoder->data[index] & (0x01 << shift)); | ||||||
| 
 |     bool pwm = timings->bit1_space == timings->bit0_space; | ||||||
|     // stop bit
 |  | ||||||
|     if (encoder->bits_encoded == encoder->protocol->databit_len) { |  | ||||||
|         furi_assert(!encoder->protocol->no_stop_bit); |  | ||||||
|         *duration = timings->bit1_mark; |  | ||||||
|         *level = true; |  | ||||||
|         ++encoder->timings_encoded; |  | ||||||
|         encoder->timings_sum += *duration; |  | ||||||
|         return IrdaStatusDone; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     if (encoder->timings_encoded % 2) {         /* start encoding from space */ |     if (encoder->timings_encoded % 2) {         /* start encoding from space */ | ||||||
|         *duration = logic_value ? timings->bit1_mark : timings->bit0_mark; |         *duration = logic_value ? timings->bit1_mark : timings->bit0_mark; | ||||||
|         *level = true; |         *level = true; | ||||||
|  |         if (pwm) | ||||||
|  |             ++encoder->bits_encoded; | ||||||
|     } else { |     } else { | ||||||
|         *duration = logic_value ? timings->bit1_space : timings->bit0_space; |         *duration = logic_value ? timings->bit1_space : timings->bit0_space; | ||||||
|         *level = false; |         *level = false; | ||||||
|  |         if (!pwm) | ||||||
|             ++encoder->bits_encoded; |             ++encoder->bits_encoded; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if ((encoder->bits_encoded == encoder->protocol->databit_len) |     return IrdaStatusOk; | ||||||
|         && encoder->protocol->no_stop_bit) { |  | ||||||
|         done = true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     ++encoder->timings_encoded; |  | ||||||
|     encoder->timings_sum += *duration; |  | ||||||
|     return done ? IrdaStatusDone : IrdaStatusOk; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| IrdaStatus irda_common_encode(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { | IrdaStatus irda_common_encode(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { | ||||||
| @ -116,7 +113,7 @@ IrdaStatus irda_common_encode(IrdaCommonEncoder* encoder, uint32_t* duration, bo | |||||||
|         } |         } | ||||||
|         /* FALLTHROUGH */ |         /* FALLTHROUGH */ | ||||||
|     case IrdaCommonEncoderStateEncode: |     case IrdaCommonEncoderStateEncode: | ||||||
|         status = encoder->protocol->encode(encoder, duration, level); |         status = irda_common_encode_bits(encoder, duration, level); | ||||||
|         if (status == IrdaStatusDone) { |         if (status == IrdaStatusDone) { | ||||||
|             if (encoder->protocol->encode_repeat) { |             if (encoder->protocol->encode_repeat) { | ||||||
|                 encoder->state = IrdaCommonEncoderStateEncodeRepeat; |                 encoder->state = IrdaCommonEncoderStateEncodeRepeat; | ||||||
| @ -138,10 +135,18 @@ IrdaStatus irda_common_encode(IrdaCommonEncoder* encoder, uint32_t* duration, bo | |||||||
| 
 | 
 | ||||||
| void* irda_common_encoder_alloc(const IrdaCommonProtocolSpec* protocol) { | void* irda_common_encoder_alloc(const IrdaCommonProtocolSpec* protocol) { | ||||||
|     furi_assert(protocol); |     furi_assert(protocol); | ||||||
|  |     if (protocol->decode == irda_common_decode_pdwm) { | ||||||
|  |         furi_assert((protocol->timings.bit1_mark == protocol->timings.bit0_mark) ^ (protocol->timings.bit1_space == protocol->timings.bit0_space)); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     uint32_t alloc_size = sizeof(IrdaCommonEncoder) |     /* protocol->databit_len[0] has to contain biggest value of bits that can be decoded */ | ||||||
|                           + protocol->databit_len / 8 |     for (int i = 1; i < COUNT_OF(protocol->databit_len); ++i) { | ||||||
|                           + !!(protocol->databit_len % 8); |         furi_assert(protocol->databit_len[i] <= protocol->databit_len[0]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     uint32_t alloc_size = sizeof(IrdaCommonDecoder) | ||||||
|  |                           + protocol->databit_len[0] / 8 | ||||||
|  |                           + !!(protocol->databit_len[0] % 8); | ||||||
|     IrdaCommonEncoder* encoder = furi_alloc(alloc_size); |     IrdaCommonEncoder* encoder = furi_alloc(alloc_size); | ||||||
|     memset(encoder, 0, alloc_size); |     memset(encoder, 0, alloc_size); | ||||||
|     encoder->protocol = protocol; |     encoder->protocol = protocol; | ||||||
| @ -162,8 +167,14 @@ void irda_common_encoder_reset(IrdaCommonEncoder* encoder) { | |||||||
|     encoder->state = IrdaCommonEncoderStateSilence; |     encoder->state = IrdaCommonEncoderStateSilence; | ||||||
|     encoder->switch_detect = 0; |     encoder->switch_detect = 0; | ||||||
| 
 | 
 | ||||||
|     uint8_t bytes_to_clear = encoder->protocol->databit_len / 8 |     uint8_t max_databit_len = 0; | ||||||
|         + !!(encoder->protocol->databit_len % 8); | 
 | ||||||
|  |     for (int i = 0; i < COUNT_OF(encoder->protocol->databit_len); ++i) { | ||||||
|  |         max_databit_len = MAX(max_databit_len, encoder->protocol->databit_len[i]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     uint8_t bytes_to_clear = max_databit_len / 8 | ||||||
|  |         + !!(max_databit_len % 8); | ||||||
|     memset(encoder->data, 0, bytes_to_clear); |     memset(encoder->data, 0, bytes_to_clear); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -11,7 +11,8 @@ | |||||||
| typedef struct IrdaCommonDecoder IrdaCommonDecoder; | typedef struct IrdaCommonDecoder IrdaCommonDecoder; | ||||||
| typedef struct IrdaCommonEncoder IrdaCommonEncoder; | typedef struct IrdaCommonEncoder IrdaCommonEncoder; | ||||||
| 
 | 
 | ||||||
| typedef IrdaStatus (*IrdaCommonDecode)(IrdaCommonDecoder*); | typedef IrdaStatus (*IrdaCommonDecode)(IrdaCommonDecoder*, bool, uint32_t); | ||||||
|  | typedef IrdaStatus (*IrdaCommonDecodeRepeat)(IrdaCommonDecoder*); | ||||||
| typedef bool (*IrdaCommonInterpret)(IrdaCommonDecoder*); | typedef bool (*IrdaCommonInterpret)(IrdaCommonDecoder*); | ||||||
| typedef IrdaStatus (*IrdaCommonEncode)(IrdaCommonEncoder* encoder, uint32_t* out, bool* polarity); | typedef IrdaStatus (*IrdaCommonEncode)(IrdaCommonEncoder* encoder, uint32_t* out, bool* polarity); | ||||||
| 
 | 
 | ||||||
| @ -19,9 +20,9 @@ typedef struct { | |||||||
|     IrdaTimings timings; |     IrdaTimings timings; | ||||||
|     bool     manchester_start_from_space; |     bool     manchester_start_from_space; | ||||||
|     bool     no_stop_bit; |     bool     no_stop_bit; | ||||||
|     uint32_t databit_len; |     uint8_t  databit_len[4]; | ||||||
|     IrdaCommonDecode decode; |     IrdaCommonDecode decode; | ||||||
|     IrdaCommonDecode decode_repeat; |     IrdaCommonDecodeRepeat decode_repeat; | ||||||
|     IrdaCommonInterpret interpret; |     IrdaCommonInterpret interpret; | ||||||
|     IrdaCommonEncode encode; |     IrdaCommonEncode encode; | ||||||
|     IrdaCommonEncode encode_repeat; |     IrdaCommonEncode encode_repeat; | ||||||
| @ -57,7 +58,8 @@ struct IrdaCommonEncoder { | |||||||
|     const IrdaCommonProtocolSpec* protocol; |     const IrdaCommonProtocolSpec* protocol; | ||||||
|     IrdaCommonStateEncoder state; |     IrdaCommonStateEncoder state; | ||||||
|     bool switch_detect; |     bool switch_detect; | ||||||
|     uint32_t bits_encoded; |     uint8_t bits_to_encode; | ||||||
|  |     uint8_t bits_encoded; | ||||||
|     uint32_t timings_sum; |     uint32_t timings_sum; | ||||||
|     uint32_t timings_encoded; |     uint32_t timings_encoded; | ||||||
|     void* context; |     void* context; | ||||||
| @ -65,12 +67,12 @@ struct IrdaCommonEncoder { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| IrdaMessage* irda_common_decode(IrdaCommonDecoder *decoder, bool level, uint32_t duration); | IrdaMessage* irda_common_decode(IrdaCommonDecoder *decoder, bool level, uint32_t duration); | ||||||
| IrdaStatus irda_common_decode_pdm(IrdaCommonDecoder* decoder); | IrdaStatus irda_common_decode_pdwm(IrdaCommonDecoder* decoder, bool level, uint32_t timing); | ||||||
| IrdaStatus irda_common_decode_pwm(IrdaCommonDecoder* decoder); | IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder, bool level, uint32_t timing); | ||||||
| IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder); |  | ||||||
| void* irda_common_decoder_alloc(const IrdaCommonProtocolSpec *protocol); | void* irda_common_decoder_alloc(const IrdaCommonProtocolSpec *protocol); | ||||||
| void irda_common_decoder_free(IrdaCommonDecoder* decoder); | void irda_common_decoder_free(IrdaCommonDecoder* decoder); | ||||||
| void irda_common_decoder_reset(IrdaCommonDecoder* decoder); | void irda_common_decoder_reset(IrdaCommonDecoder* decoder); | ||||||
|  | IrdaMessage* irda_common_decoder_check_ready(IrdaCommonDecoder* decoder); | ||||||
| 
 | 
 | ||||||
| IrdaStatus irda_common_encode(IrdaCommonEncoder* encoder, uint32_t* duration, bool* polarity); | IrdaStatus irda_common_encode(IrdaCommonEncoder* encoder, uint32_t* duration, bool* polarity); | ||||||
| IrdaStatus irda_common_encode_pdwm(IrdaCommonEncoder* encoder, uint32_t* duration, bool* polarity); | IrdaStatus irda_common_encode_pdwm(IrdaCommonEncoder* encoder, uint32_t* duration, bool* polarity); | ||||||
|  | |||||||
| @ -12,10 +12,12 @@ const IrdaCommonProtocolSpec protocol_nec = { | |||||||
|         .preamble_tolerance = IRDA_NEC_PREAMBLE_TOLERANCE, |         .preamble_tolerance = IRDA_NEC_PREAMBLE_TOLERANCE, | ||||||
|         .bit_tolerance = IRDA_NEC_BIT_TOLERANCE, |         .bit_tolerance = IRDA_NEC_BIT_TOLERANCE, | ||||||
|         .silence_time = IRDA_NEC_SILENCE, |         .silence_time = IRDA_NEC_SILENCE, | ||||||
|  |         .min_split_time = IRDA_NEC_MIN_SPLIT_TIME, | ||||||
|     }, |     }, | ||||||
|     .databit_len = 32, |     .databit_len[0] = 42, | ||||||
|  |     .databit_len[1] = 32, | ||||||
|     .no_stop_bit = false, |     .no_stop_bit = false, | ||||||
|     .decode = irda_common_decode_pdm, |     .decode = irda_common_decode_pdwm, | ||||||
|     .encode = irda_common_encode_pdwm, |     .encode = irda_common_encode_pdwm, | ||||||
|     .interpret = irda_decoder_nec_interpret, |     .interpret = irda_decoder_nec_interpret, | ||||||
|     .decode_repeat = irda_decoder_nec_decode_repeat, |     .decode_repeat = irda_decoder_nec_decode_repeat, | ||||||
| @ -34,9 +36,9 @@ const IrdaCommonProtocolSpec protocol_samsung32 = { | |||||||
|         .bit_tolerance = IRDA_SAMSUNG_BIT_TOLERANCE, |         .bit_tolerance = IRDA_SAMSUNG_BIT_TOLERANCE, | ||||||
|         .silence_time = IRDA_SAMSUNG_SILENCE, |         .silence_time = IRDA_SAMSUNG_SILENCE, | ||||||
|     }, |     }, | ||||||
|     .databit_len = 32, |     .databit_len[0] = 32, | ||||||
|     .no_stop_bit = false, |     .no_stop_bit = false, | ||||||
|     .decode = irda_common_decode_pdm, |     .decode = irda_common_decode_pdwm, | ||||||
|     .encode = irda_common_encode_pdwm, |     .encode = irda_common_encode_pdwm, | ||||||
|     .interpret = irda_decoder_samsung32_interpret, |     .interpret = irda_decoder_samsung32_interpret, | ||||||
|     .decode_repeat = irda_decoder_samsung32_decode_repeat, |     .decode_repeat = irda_decoder_samsung32_decode_repeat, | ||||||
| @ -52,7 +54,7 @@ const IrdaCommonProtocolSpec protocol_rc6 = { | |||||||
|         .bit_tolerance = IRDA_RC6_BIT_TOLERANCE, |         .bit_tolerance = IRDA_RC6_BIT_TOLERANCE, | ||||||
|         .silence_time = IRDA_RC6_SILENCE, |         .silence_time = IRDA_RC6_SILENCE, | ||||||
|     }, |     }, | ||||||
|     .databit_len = 1 + 3 + 1 + 8 + 8,   // start_bit + 3 mode bits, + 1 toggle bit (x2 timing) + 8 address + 8 command
 |     .databit_len[0] = 1 + 3 + 1 + 8 + 8,   // start_bit + 3 mode bits, + 1 toggle bit (x2 timing) + 8 address + 8 command
 | ||||||
|     .manchester_start_from_space = false, |     .manchester_start_from_space = false, | ||||||
|     .decode = irda_decoder_rc6_decode_manchester, |     .decode = irda_decoder_rc6_decode_manchester, | ||||||
|     .encode = irda_encoder_rc6_encode_manchester, |     .encode = irda_encoder_rc6_encode_manchester, | ||||||
| @ -70,7 +72,7 @@ const IrdaCommonProtocolSpec protocol_rc5 = { | |||||||
|         .bit_tolerance = IRDA_RC5_BIT_TOLERANCE, |         .bit_tolerance = IRDA_RC5_BIT_TOLERANCE, | ||||||
|         .silence_time = IRDA_RC5_SILENCE, |         .silence_time = IRDA_RC5_SILENCE, | ||||||
|     }, |     }, | ||||||
|     .databit_len = 1 + 1 + 1 + 5 + 6,   // start_bit + start_bit/command_bit + toggle_bit + 5 address + 6 command
 |     .databit_len[0] = 1 + 1 + 1 + 5 + 6,   // start_bit + start_bit/command_bit + toggle_bit + 5 address + 6 command
 | ||||||
|     .manchester_start_from_space = true, |     .manchester_start_from_space = true, | ||||||
|     .decode = irda_common_decode_manchester, |     .decode = irda_common_decode_manchester, | ||||||
|     .encode = irda_common_encode_manchester, |     .encode = irda_common_encode_manchester, | ||||||
| @ -90,10 +92,13 @@ const IrdaCommonProtocolSpec protocol_sirc = { | |||||||
|         .preamble_tolerance = IRDA_SIRC_PREAMBLE_TOLERANCE, |         .preamble_tolerance = IRDA_SIRC_PREAMBLE_TOLERANCE, | ||||||
|         .bit_tolerance = IRDA_SIRC_BIT_TOLERANCE, |         .bit_tolerance = IRDA_SIRC_BIT_TOLERANCE, | ||||||
|         .silence_time = IRDA_SIRC_SILENCE, |         .silence_time = IRDA_SIRC_SILENCE, | ||||||
|  |         .min_split_time = IRDA_SIRC_MIN_SPLIT_TIME, | ||||||
|     }, |     }, | ||||||
|     .databit_len = 20,  /* 12/15/20 */ |     .databit_len[0] = 20, | ||||||
|  |     .databit_len[1] = 15, | ||||||
|  |     .databit_len[2] = 12, | ||||||
|     .no_stop_bit = true, |     .no_stop_bit = true, | ||||||
|     .decode = irda_common_decode_pwm, |     .decode = irda_common_decode_pdwm, | ||||||
|     .encode = irda_common_encode_pdwm, |     .encode = irda_common_encode_pdwm, | ||||||
|     .interpret = irda_decoder_sirc_interpret, |     .interpret = irda_decoder_sirc_interpret, | ||||||
|     .decode_repeat = NULL, |     .decode_repeat = NULL, | ||||||
|  | |||||||
| @ -45,6 +45,7 @@ static const IrdaEncoderDecoder irda_encoder_decoder[] = { | |||||||
|           .alloc = irda_decoder_nec_alloc, |           .alloc = irda_decoder_nec_alloc, | ||||||
|           .decode = irda_decoder_nec_decode, |           .decode = irda_decoder_nec_decode, | ||||||
|           .reset = irda_decoder_nec_reset, |           .reset = irda_decoder_nec_reset, | ||||||
|  |           .check_ready = irda_decoder_nec_check_ready, | ||||||
|           .free = irda_decoder_nec_free}, |           .free = irda_decoder_nec_free}, | ||||||
|       .encoder = { |       .encoder = { | ||||||
|           .alloc = irda_encoder_nec_alloc, |           .alloc = irda_encoder_nec_alloc, | ||||||
|  | |||||||
| @ -21,14 +21,16 @@ typedef struct IrdaEncoderHandler IrdaEncoderHandler; | |||||||
| typedef enum { | typedef enum { | ||||||
|     IrdaProtocolUnknown = -1, |     IrdaProtocolUnknown = -1, | ||||||
|     IrdaProtocolNEC = 0, |     IrdaProtocolNEC = 0, | ||||||
|     IrdaProtocolNECext = 1, |     IrdaProtocolNECext, | ||||||
|     IrdaProtocolSamsung32 = 2, |     IrdaProtocolNEC42, | ||||||
|     IrdaProtocolRC6 = 3, |     IrdaProtocolNEC42ext, | ||||||
|     IrdaProtocolRC5 = 4, |     IrdaProtocolSamsung32, | ||||||
|     IrdaProtocolRC5X = 5, |     IrdaProtocolRC6, | ||||||
|     IrdaProtocolSIRC = 6, |     IrdaProtocolRC5, | ||||||
|     IrdaProtocolSIRC15 = 7, |     IrdaProtocolRC5X, | ||||||
|     IrdaProtocolSIRC20 = 8, |     IrdaProtocolSIRC, | ||||||
|  |     IrdaProtocolSIRC15, | ||||||
|  |     IrdaProtocolSIRC20, | ||||||
|     IrdaProtocolMAX, |     IrdaProtocolMAX, | ||||||
| } IrdaProtocol; | } IrdaProtocol; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ | |||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|  |     uint32_t min_split_time; | ||||||
|     uint32_t silence_time; |     uint32_t silence_time; | ||||||
|     uint16_t preamble_mark; |     uint16_t preamble_mark; | ||||||
|     uint16_t preamble_space; |     uint16_t preamble_space; | ||||||
|  | |||||||
| @ -23,12 +23,13 @@ | |||||||
| #define IRDA_NEC_PREAMBLE_MARK          9000 | #define IRDA_NEC_PREAMBLE_MARK          9000 | ||||||
| #define IRDA_NEC_PREAMBLE_SPACE         4500 | #define IRDA_NEC_PREAMBLE_SPACE         4500 | ||||||
| #define IRDA_NEC_BIT1_MARK              560 | #define IRDA_NEC_BIT1_MARK              560 | ||||||
| #define IRDA_NEC_BIT1_SPACE             1600 | #define IRDA_NEC_BIT1_SPACE             1690 | ||||||
| #define IRDA_NEC_BIT0_MARK              560 | #define IRDA_NEC_BIT0_MARK              560 | ||||||
| #define IRDA_NEC_BIT0_SPACE             560 | #define IRDA_NEC_BIT0_SPACE             560 | ||||||
| #define IRDA_NEC_REPEAT_PERIOD          110000 | #define IRDA_NEC_REPEAT_PERIOD          110000 | ||||||
| #define IRDA_NEC_SILENCE                IRDA_NEC_REPEAT_PERIOD | #define IRDA_NEC_SILENCE                IRDA_NEC_REPEAT_PERIOD | ||||||
| #define IRDA_NEC_REPEAT_PAUSE_MIN       30000 | #define IRDA_NEC_MIN_SPLIT_TIME         IRDA_NEC_REPEAT_PAUSE_MIN | ||||||
|  | #define IRDA_NEC_REPEAT_PAUSE_MIN       4000 | ||||||
| #define IRDA_NEC_REPEAT_PAUSE_MAX       150000 | #define IRDA_NEC_REPEAT_PAUSE_MAX       150000 | ||||||
| #define IRDA_NEC_REPEAT_MARK            9000 | #define IRDA_NEC_REPEAT_MARK            9000 | ||||||
| #define IRDA_NEC_REPEAT_SPACE           2250 | #define IRDA_NEC_REPEAT_SPACE           2250 | ||||||
| @ -38,6 +39,7 @@ | |||||||
| void* irda_decoder_nec_alloc(void); | void* irda_decoder_nec_alloc(void); | ||||||
| void irda_decoder_nec_reset(void* decoder); | void irda_decoder_nec_reset(void* decoder); | ||||||
| void irda_decoder_nec_free(void* decoder); | void irda_decoder_nec_free(void* decoder); | ||||||
|  | IrdaMessage* irda_decoder_nec_check_ready(void* decoder); | ||||||
| IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duration); | IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duration); | ||||||
| void* irda_encoder_nec_alloc(void); | void* irda_encoder_nec_alloc(void); | ||||||
| IrdaStatus irda_encoder_nec_encode(void* encoder_ptr, uint32_t* duration, bool* level); | IrdaStatus irda_encoder_nec_encode(void* encoder_ptr, uint32_t* duration, bool* level); | ||||||
| @ -143,7 +145,7 @@ void irda_encoder_rc6_reset(void* encoder_ptr, const IrdaMessage* message); | |||||||
| void irda_encoder_rc6_free(void* decoder); | void irda_encoder_rc6_free(void* decoder); | ||||||
| IrdaStatus irda_encoder_rc6_encode(void* encoder_ptr, uint32_t* duration, bool* polarity); | IrdaStatus irda_encoder_rc6_encode(void* encoder_ptr, uint32_t* duration, bool* polarity); | ||||||
| bool irda_decoder_rc6_interpret(IrdaCommonDecoder* decoder); | bool irda_decoder_rc6_interpret(IrdaCommonDecoder* decoder); | ||||||
| IrdaStatus irda_decoder_rc6_decode_manchester(IrdaCommonDecoder* decoder); | IrdaStatus irda_decoder_rc6_decode_manchester(IrdaCommonDecoder* decoder, bool level, uint32_t timing); | ||||||
| IrdaStatus irda_encoder_rc6_encode_manchester(IrdaCommonEncoder* encoder_ptr, uint32_t* duration, bool* polarity); | IrdaStatus irda_encoder_rc6_encode_manchester(IrdaCommonEncoder* encoder_ptr, uint32_t* duration, bool* polarity); | ||||||
| const IrdaProtocolSpecification* irda_rc6_get_spec(IrdaProtocol protocol); | const IrdaProtocolSpecification* irda_rc6_get_spec(IrdaProtocol protocol); | ||||||
| 
 | 
 | ||||||
| @ -229,7 +231,7 @@ extern const IrdaCommonProtocolSpec protocol_rc5; | |||||||
| #define IRDA_SIRC_PREAMBLE_TOLERANCE           200     // us
 | #define IRDA_SIRC_PREAMBLE_TOLERANCE           200     // us
 | ||||||
| #define IRDA_SIRC_BIT_TOLERANCE                120     // us
 | #define IRDA_SIRC_BIT_TOLERANCE                120     // us
 | ||||||
| #define IRDA_SIRC_SILENCE                      10000 | #define IRDA_SIRC_SILENCE                      10000 | ||||||
| #define IRDA_SIRC_MIN_SILENCE                  (IRDA_SIRC_SILENCE - 1000) | #define IRDA_SIRC_MIN_SPLIT_TIME               (IRDA_SIRC_SILENCE - 1000) | ||||||
| #define IRDA_SIRC_REPEAT_PERIOD                45000 | #define IRDA_SIRC_REPEAT_PERIOD                45000 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,3 +1,4 @@ | |||||||
|  | #include "common/irda_common_i.h" | ||||||
| #include "irda.h" | #include "irda.h" | ||||||
| #include "irda_protocol_defs_i.h" | #include "irda_protocol_defs_i.h" | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| @ -6,26 +7,55 @@ | |||||||
| #include "../irda_i.h" | #include "../irda_i.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | IrdaMessage* irda_decoder_nec_check_ready(void* ctx) { | ||||||
|  |     return irda_common_decoder_check_ready(ctx); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool irda_decoder_nec_interpret(IrdaCommonDecoder* decoder) { | bool irda_decoder_nec_interpret(IrdaCommonDecoder* decoder) { | ||||||
|     furi_assert(decoder); |     furi_assert(decoder); | ||||||
| 
 | 
 | ||||||
|     bool result = false; |     bool result = false; | ||||||
|  | 
 | ||||||
|  |     if (decoder->databit_cnt == 32) { | ||||||
|         uint8_t address = decoder->data[0]; |         uint8_t address = decoder->data[0]; | ||||||
|         uint8_t address_inverse = decoder->data[1]; |         uint8_t address_inverse = decoder->data[1]; | ||||||
|         uint8_t command = decoder->data[2]; |         uint8_t command = decoder->data[2]; | ||||||
|         uint8_t command_inverse = decoder->data[3]; |         uint8_t command_inverse = decoder->data[3]; | ||||||
| 
 |         if ((command == (uint8_t) ~command_inverse) && (address == (uint8_t) ~address_inverse)) { | ||||||
|     if (command == (uint8_t) ~command_inverse) { |  | ||||||
|         if (address == (uint8_t) ~address_inverse) { |  | ||||||
|             decoder->message.protocol = IrdaProtocolNEC; |             decoder->message.protocol = IrdaProtocolNEC; | ||||||
|             decoder->message.address = address; |             decoder->message.address = address; | ||||||
|         } else { |  | ||||||
|             decoder->message.protocol = IrdaProtocolNECext; |  | ||||||
|             decoder->message.address = decoder->data[0] | (decoder->data[1] << 8); |  | ||||||
|         } |  | ||||||
|             decoder->message.command = command; |             decoder->message.command = command; | ||||||
|             decoder->message.repeat = false; |             decoder->message.repeat = false; | ||||||
|             result = true; |             result = true; | ||||||
|  |         } else { | ||||||
|  |             decoder->message.protocol = IrdaProtocolNECext; | ||||||
|  |             decoder->message.address = decoder->data[0] | (decoder->data[1] << 8); | ||||||
|  |             decoder->message.command = decoder->data[2] | (decoder->data[3] << 8); | ||||||
|  |             decoder->message.repeat = false; | ||||||
|  |             result = true; | ||||||
|  |         } | ||||||
|  |     } else if (decoder->databit_cnt == 42) { | ||||||
|  |         uint32_t* data1 = (void*) decoder->data; | ||||||
|  |         uint16_t* data2 = (void*) (data1 + 1); | ||||||
|  |         uint16_t address = *data1 & 0x1FFF; | ||||||
|  |         uint16_t address_inverse = (*data1 >> 13) & 0x1FFF; | ||||||
|  |         uint16_t command = ((*data1 >> 26) & 0x3F) | ((*data2 & 0x3) << 6); | ||||||
|  |         uint16_t command_inverse = (*data2 >> 2) & 0xFF; | ||||||
|  | 
 | ||||||
|  |         if ((address == (~address_inverse & 0x1FFF)) | ||||||
|  |             && (command == (~command_inverse & 0xFF))) { | ||||||
|  |             decoder->message.protocol = IrdaProtocolNEC42; | ||||||
|  |             decoder->message.address = address; | ||||||
|  |             decoder->message.command = command; | ||||||
|  |             decoder->message.repeat = false; | ||||||
|  |             result = true; | ||||||
|  |         } else { | ||||||
|  |             decoder->message.protocol = IrdaProtocolNEC42ext; | ||||||
|  |             decoder->message.address = address | (address_inverse << 13); | ||||||
|  |             decoder->message.command = command | (command_inverse << 8); | ||||||
|  |             decoder->message.repeat = false; | ||||||
|  |             result = true; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return result; |     return result; | ||||||
|  | |||||||
| @ -20,26 +20,45 @@ void irda_encoder_nec_reset(void* encoder_ptr, const IrdaMessage* message) { | |||||||
|     IrdaCommonEncoder* encoder = encoder_ptr; |     IrdaCommonEncoder* encoder = encoder_ptr; | ||||||
|     irda_common_encoder_reset(encoder); |     irda_common_encoder_reset(encoder); | ||||||
| 
 | 
 | ||||||
|  |     uint32_t* data1 = (void*) encoder->data; | ||||||
|  |     uint32_t* data2 = data1 + 1; | ||||||
|  |     if (message->protocol == IrdaProtocolNEC) { | ||||||
|         uint8_t address = message->address; |         uint8_t address = message->address; | ||||||
|         uint8_t address_inverse = ~address; |         uint8_t address_inverse = ~address; | ||||||
|         uint8_t command = message->command; |         uint8_t command = message->command; | ||||||
|         uint8_t command_inverse = ~command; |         uint8_t command_inverse = ~command; | ||||||
| 
 |         *data1 = address; | ||||||
|     uint32_t* data = (void*) encoder->data; |         *data1 |= address_inverse << 8; | ||||||
|     if (message->protocol == IrdaProtocolNEC) { |         *data1 |= command << 16; | ||||||
|         *data = (address | (address_inverse << 8)); |         *data1 |= command_inverse << 24; | ||||||
|  |         encoder->bits_to_encode = 32; | ||||||
|     } else if (message->protocol == IrdaProtocolNECext) { |     } else if (message->protocol == IrdaProtocolNECext) { | ||||||
|         *data = (uint16_t) message->address; |         *data1 = (uint16_t) message->address; | ||||||
|  |         *data1 |= (message->command & 0xFFFF) << 16; | ||||||
|  |         encoder->bits_to_encode = 32; | ||||||
|  |     } else if (message->protocol == IrdaProtocolNEC42) { | ||||||
|  |         /* 13 address + 13 inverse address + 8 command + 8 inv command */ | ||||||
|  |         *data1 = message->address & 0x1FFFUL; | ||||||
|  |         *data1 |= (~message->address & 0x1FFFUL) << 13; | ||||||
|  |         *data1 |= ((message->command & 0x3FUL) << 26); | ||||||
|  |         *data2 = (message->command & 0xC0UL) >> 6; | ||||||
|  |         *data2 |= (~message->command & 0xFFUL) << 2; | ||||||
|  |         encoder->bits_to_encode = 42; | ||||||
|  |     } else if (message->protocol == IrdaProtocolNEC42ext) { | ||||||
|  |         *data1 = message->address & 0x3FFFFFF; | ||||||
|  |         *data1 |= ((message->command & 0x3F) << 26); | ||||||
|  |         *data2 = (message->command & 0xFFC0) >> 6; | ||||||
|  |         encoder->bits_to_encode = 42; | ||||||
|  |     } else { | ||||||
|  |         furi_assert(0); | ||||||
|     } |     } | ||||||
|     *data |= command << 16; |  | ||||||
|     *data |= command_inverse << 24; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| IrdaStatus irda_encoder_nec_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { | IrdaStatus irda_encoder_nec_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { | ||||||
|     furi_assert(encoder); |     furi_assert(encoder); | ||||||
| 
 | 
 | ||||||
|     /* space + 2 timings preambule + payload + stop bit */ |     /* space + 2 timings preambule + payload + stop bit */ | ||||||
|     uint32_t timings_encoded_up_to_repeat = 1 + 2 + encoder->protocol->databit_len * 2 + 1; |     uint32_t timings_encoded_up_to_repeat = 1 + 2 + encoder->bits_to_encode * 2 + 1; | ||||||
|     uint32_t repeat_cnt = encoder->timings_encoded - timings_encoded_up_to_repeat; |     uint32_t repeat_cnt = encoder->timings_encoded - timings_encoded_up_to_repeat; | ||||||
| 
 | 
 | ||||||
|     furi_assert(encoder->timings_encoded >= timings_encoded_up_to_repeat); |     furi_assert(encoder->timings_encoded >= timings_encoded_up_to_repeat); | ||||||
|  | |||||||
| @ -12,16 +12,36 @@ static const IrdaProtocolSpecification irda_nec_protocol_specification = { | |||||||
| static const IrdaProtocolSpecification irda_necext_protocol_specification = { | static const IrdaProtocolSpecification irda_necext_protocol_specification = { | ||||||
|       .name = "NECext", |       .name = "NECext", | ||||||
|       .address_length = 16, |       .address_length = 16, | ||||||
|  |       .command_length = 16, | ||||||
|  |       .frequency = IRDA_COMMON_CARRIER_FREQUENCY, | ||||||
|  |       .duty_cycle = IRDA_COMMON_DUTY_CYCLE, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const IrdaProtocolSpecification irda_nec42_protocol_specification = { | ||||||
|  |       .name = "NEC42", | ||||||
|  |       .address_length = 13, | ||||||
|       .command_length = 8, |       .command_length = 8, | ||||||
|       .frequency = IRDA_COMMON_CARRIER_FREQUENCY, |       .frequency = IRDA_COMMON_CARRIER_FREQUENCY, | ||||||
|       .duty_cycle = IRDA_COMMON_DUTY_CYCLE, |       .duty_cycle = IRDA_COMMON_DUTY_CYCLE, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | static const IrdaProtocolSpecification irda_nec42ext_protocol_specification = { | ||||||
|  |       .name = "NEC42ext", | ||||||
|  |       .address_length = 26, | ||||||
|  |       .command_length = 16, | ||||||
|  |       .frequency = IRDA_COMMON_CARRIER_FREQUENCY, | ||||||
|  |       .duty_cycle = IRDA_COMMON_DUTY_CYCLE, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| const IrdaProtocolSpecification* irda_nec_get_spec(IrdaProtocol protocol) { | const IrdaProtocolSpecification* irda_nec_get_spec(IrdaProtocol protocol) { | ||||||
|     if (protocol == IrdaProtocolNEC) |     if (protocol == IrdaProtocolNEC) | ||||||
|         return &irda_nec_protocol_specification; |         return &irda_nec_protocol_specification; | ||||||
|     else if (protocol == IrdaProtocolNECext) |     else if (protocol == IrdaProtocolNECext) | ||||||
|         return &irda_necext_protocol_specification; |         return &irda_necext_protocol_specification; | ||||||
|  |     else if (protocol == IrdaProtocolNEC42) | ||||||
|  |         return &irda_nec42_protocol_specification; | ||||||
|  |     else if (protocol == IrdaProtocolNEC42ext) | ||||||
|  |         return &irda_nec42ext_protocol_specification; | ||||||
|     else |     else | ||||||
|         return NULL; |         return NULL; | ||||||
| } | } | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ void irda_encoder_rc5_reset(void* encoder_ptr, const IrdaMessage* message) { | |||||||
|     common_encoder->data[0] = ~common_encoder->data[0]; |     common_encoder->data[0] = ~common_encoder->data[0]; | ||||||
|     common_encoder->data[1] = ~common_encoder->data[1]; |     common_encoder->data[1] = ~common_encoder->data[1]; | ||||||
| 
 | 
 | ||||||
|  |     common_encoder->bits_to_encode = common_encoder->protocol->databit_len[0]; | ||||||
|     encoder->toggle_bit ^= 1; |     encoder->toggle_bit ^= 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -50,39 +50,35 @@ bool irda_decoder_rc6_interpret(IrdaCommonDecoder* decoder) { | |||||||
|  * it separately and than pass decoding for other bits to |  * it separately and than pass decoding for other bits to | ||||||
|  * common manchester decode function. |  * common manchester decode function. | ||||||
|  */ |  */ | ||||||
| IrdaStatus irda_decoder_rc6_decode_manchester(IrdaCommonDecoder* decoder) { | IrdaStatus irda_decoder_rc6_decode_manchester(IrdaCommonDecoder* decoder, bool level, uint32_t timing) { | ||||||
|     // 4th bit lasts 2x times more
 |     // 4th bit lasts 2x times more
 | ||||||
|     IrdaStatus status = IrdaStatusError; |     IrdaStatus status = IrdaStatusError; | ||||||
|     uint16_t bit = decoder->protocol->timings.bit1_mark; |     uint16_t bit = decoder->protocol->timings.bit1_mark; | ||||||
|     uint16_t tolerance = decoder->protocol->timings.bit_tolerance; |     uint16_t tolerance = decoder->protocol->timings.bit_tolerance; | ||||||
|     uint16_t timing = decoder->timings[0]; |  | ||||||
| 
 | 
 | ||||||
|     bool single_timing = MATCH_TIMING(timing, bit, tolerance); |     bool single_timing = MATCH_TIMING(timing, bit, tolerance); | ||||||
|     bool double_timing = MATCH_TIMING(timing, 2*bit, tolerance); |     bool double_timing = MATCH_TIMING(timing, 2*bit, tolerance); | ||||||
|     bool triple_timing = MATCH_TIMING(timing, 3*bit, tolerance); |     bool triple_timing = MATCH_TIMING(timing, 3*bit, tolerance); | ||||||
| 
 | 
 | ||||||
|     if (decoder->databit_cnt == 4) { |     if (decoder->databit_cnt == 4) { | ||||||
|         furi_assert(decoder->timings_cnt == 1); |  | ||||||
|         furi_assert(decoder->switch_detect == true); |         furi_assert(decoder->switch_detect == true); | ||||||
| 
 | 
 | ||||||
|         if (single_timing ^ triple_timing) { |         if (single_timing ^ triple_timing) { | ||||||
|             --decoder->timings_cnt; |  | ||||||
|             ++decoder->databit_cnt; |             ++decoder->databit_cnt; | ||||||
|             decoder->data[0] |= (single_timing ? !decoder->level : decoder->level) << 4; |             decoder->data[0] |= (single_timing ? !level : level) << 4; | ||||||
|             status = IrdaStatusOk; |             status = IrdaStatusOk; | ||||||
|         } |         } | ||||||
|     } else if (decoder->databit_cnt == 5) { |     } else if (decoder->databit_cnt == 5) { | ||||||
|         if (single_timing || triple_timing) { |         if (single_timing || triple_timing) { | ||||||
|             if (triple_timing) |             if (triple_timing) | ||||||
|                 decoder->timings[0] = bit; |                 timing = bit; | ||||||
|             decoder->switch_detect = false; |             decoder->switch_detect = false; | ||||||
|             status = irda_common_decode_manchester(decoder); |             status = irda_common_decode_manchester(decoder, level, timing); | ||||||
|         } else if (double_timing) { |         } else if (double_timing) { | ||||||
|             --decoder->timings_cnt; |  | ||||||
|             status = IrdaStatusOk; |             status = IrdaStatusOk; | ||||||
|         } |         } | ||||||
|     } else { |     } else { | ||||||
|         status = irda_common_decode_manchester(decoder); |         status = irda_common_decode_manchester(decoder, level, timing); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return status; |     return status; | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ void irda_encoder_rc6_reset(void* encoder_ptr, const IrdaMessage* message) { | |||||||
|     *data |= reverse(message->address) << 5; |     *data |= reverse(message->address) << 5; | ||||||
|     *data |= reverse(message->command) << 13; |     *data |= reverse(message->command) << 13; | ||||||
| 
 | 
 | ||||||
|  |     common_encoder->bits_to_encode = common_encoder->protocol->databit_len[0]; | ||||||
|     encoder->toggle_bit ^= 1; |     encoder->toggle_bit ^= 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -29,13 +29,15 @@ void irda_encoder_samsung32_reset(void* encoder_ptr, const IrdaMessage* message) | |||||||
|     *data |= address << 8; |     *data |= address << 8; | ||||||
|     *data |= command << 16; |     *data |= command << 16; | ||||||
|     *data |= command_inverse << 24; |     *data |= command_inverse << 24; | ||||||
|  | 
 | ||||||
|  |     encoder->bits_to_encode = encoder->protocol->databit_len[0]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| IrdaStatus irda_encoder_samsung32_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { | IrdaStatus irda_encoder_samsung32_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { | ||||||
|     furi_assert(encoder); |     furi_assert(encoder); | ||||||
| 
 | 
 | ||||||
|     /* space + 2 timings preambule + payload + stop bit */ |     /* space + 2 timings preambule + payload + stop bit */ | ||||||
|     uint32_t timings_encoded_up_to_repeat = 1 + 2 + encoder->protocol->databit_len * 2 + 1; |     uint32_t timings_encoded_up_to_repeat = 1 + 2 + encoder->bits_encoded * 2 + 1; | ||||||
|     uint32_t repeat_cnt = encoder->timings_encoded - timings_encoded_up_to_repeat; |     uint32_t repeat_cnt = encoder->timings_encoded - timings_encoded_up_to_repeat; | ||||||
| 
 | 
 | ||||||
|     furi_assert(encoder->timings_encoded >= timings_encoded_up_to_repeat); |     furi_assert(encoder->timings_encoded >= timings_encoded_up_to_repeat); | ||||||
|  | |||||||
| @ -8,16 +8,7 @@ | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| IrdaMessage* irda_decoder_sirc_check_ready(void* ctx) { | IrdaMessage* irda_decoder_sirc_check_ready(void* ctx) { | ||||||
|     IrdaMessage* message = NULL; |     return irda_common_decoder_check_ready(ctx); | ||||||
|     IrdaCommonDecoder* decoder = ctx; |  | ||||||
| 
 |  | ||||||
|     if (irda_decoder_sirc_interpret(decoder)) { |  | ||||||
|         message = &decoder->message; |  | ||||||
|         decoder->timings_cnt = 0; |  | ||||||
|         decoder->databit_cnt = 0; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return message; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool irda_decoder_sirc_interpret(IrdaCommonDecoder* decoder) { | bool irda_decoder_sirc_interpret(IrdaCommonDecoder* decoder) { | ||||||
| @ -57,29 +48,8 @@ void* irda_decoder_sirc_alloc(void) { | |||||||
|     return irda_common_decoder_alloc(&protocol_sirc); |     return irda_common_decoder_alloc(&protocol_sirc); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| IrdaMessage* irda_decoder_sirc_decode(void* context, bool level, uint32_t duration) { | IrdaMessage* irda_decoder_sirc_decode(void* decoder, bool level, uint32_t duration) { | ||||||
|     IrdaCommonDecoder* decoder = context; |     return irda_common_decode(decoder, level, duration); | ||||||
|     IrdaMessage* message = NULL; |  | ||||||
| 
 |  | ||||||
|     if ((decoder->databit_cnt == 12) || (decoder->databit_cnt == 15)) { |  | ||||||
|         if (!level && (duration >= IRDA_SIRC_MIN_SILENCE)) { |  | ||||||
|             if (irda_decoder_sirc_interpret(decoder)) { |  | ||||||
|                 message = &decoder->message; |  | ||||||
|                 decoder->timings_cnt = 0; |  | ||||||
|                 decoder->databit_cnt = 0; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (!message) { |  | ||||||
|         message = irda_common_decode(decoder, level, duration); |  | ||||||
|         if (message) {  /* 20 bit */ |  | ||||||
|             decoder->timings_cnt = 0; |  | ||||||
|             decoder->databit_cnt = 0; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return message; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void irda_decoder_sirc_free(void* decoder) { | void irda_decoder_sirc_free(void* decoder) { | ||||||
|  | |||||||
| @ -7,34 +7,27 @@ | |||||||
| #include <furi.h> | #include <furi.h> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| typedef struct { |  | ||||||
|     IrdaCommonEncoder* common_encoder; |  | ||||||
|     uint8_t databits; |  | ||||||
| } IrdaSircEncoder; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| void irda_encoder_sirc_reset(void* encoder_ptr, const IrdaMessage* message) { | void irda_encoder_sirc_reset(void* encoder_ptr, const IrdaMessage* message) { | ||||||
|     furi_assert(encoder_ptr); |     furi_assert(encoder_ptr); | ||||||
|     furi_assert(message); |     furi_assert(message); | ||||||
| 
 | 
 | ||||||
|     IrdaCommonEncoder* encoder = encoder_ptr; |     IrdaCommonEncoder* encoder = encoder_ptr; | ||||||
|     IrdaSircEncoder* encoder_sirc = encoder->context; |  | ||||||
|     irda_common_encoder_reset(encoder); |     irda_common_encoder_reset(encoder); | ||||||
| 
 | 
 | ||||||
|     uint32_t* data = (void*) encoder->data; |     uint32_t* data = (void*) encoder->data; | ||||||
| 
 | 
 | ||||||
|     if (message->protocol == IrdaProtocolSIRC) { |     if (message->protocol == IrdaProtocolSIRC) { | ||||||
|         encoder_sirc->databits = 12; |  | ||||||
|         *data = (message->command & 0x7F); |         *data = (message->command & 0x7F); | ||||||
|         *data |= (message->address & 0x1F) << 7; |         *data |= (message->address & 0x1F) << 7; | ||||||
|  |         encoder->bits_to_encode = 12; | ||||||
|     } else if (message->protocol == IrdaProtocolSIRC15) { |     } else if (message->protocol == IrdaProtocolSIRC15) { | ||||||
|         encoder_sirc->databits = 15; |  | ||||||
|         *data = (message->command & 0x7F); |         *data = (message->command & 0x7F); | ||||||
|         *data |= (message->address & 0xFF) << 7; |         *data |= (message->address & 0xFF) << 7; | ||||||
|  |         encoder->bits_to_encode = 15; | ||||||
|     } else if (message->protocol == IrdaProtocolSIRC20) { |     } else if (message->protocol == IrdaProtocolSIRC20) { | ||||||
|         encoder_sirc->databits = 20; |  | ||||||
|         *data = (message->command & 0x7F); |         *data = (message->command & 0x7F); | ||||||
|         *data |= (message->address & 0x1FFF) << 7; |         *data |= (message->address & 0x1FFF) << 7; | ||||||
|  |         encoder->bits_to_encode = 20; | ||||||
|     } else { |     } else { | ||||||
|         furi_assert(0); |         furi_assert(0); | ||||||
|     } |     } | ||||||
| @ -43,9 +36,7 @@ void irda_encoder_sirc_reset(void* encoder_ptr, const IrdaMessage* message) { | |||||||
| IrdaStatus irda_encoder_sirc_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { | IrdaStatus irda_encoder_sirc_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* duration, bool* level) { | ||||||
|     furi_assert(encoder); |     furi_assert(encoder); | ||||||
| 
 | 
 | ||||||
|     IrdaSircEncoder* encoder_sirc = encoder->context; |     uint32_t timings_in_message = 1 + 2 + encoder->bits_to_encode * 2 - 1; | ||||||
| 
 |  | ||||||
|     uint32_t timings_in_message = 1 + 2 + encoder_sirc->databits * 2; |  | ||||||
|     furi_assert(encoder->timings_encoded == timings_in_message); |     furi_assert(encoder->timings_encoded == timings_in_message); | ||||||
| 
 | 
 | ||||||
|     furi_assert(encoder->timings_sum < IRDA_SIRC_REPEAT_PERIOD); |     furi_assert(encoder->timings_sum < IRDA_SIRC_REPEAT_PERIOD); | ||||||
| @ -61,28 +52,21 @@ IrdaStatus irda_encoder_sirc_encode_repeat(IrdaCommonEncoder* encoder, uint32_t* | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void* irda_encoder_sirc_alloc(void) { | void* irda_encoder_sirc_alloc(void) { | ||||||
|     IrdaCommonEncoder* encoder_common = irda_common_encoder_alloc(&protocol_sirc); |     return irda_common_encoder_alloc(&protocol_sirc); | ||||||
|     IrdaSircEncoder* encoder_sirc = furi_alloc(sizeof(IrdaSircEncoder)); |  | ||||||
|     encoder_sirc->common_encoder = encoder_common; |  | ||||||
|     encoder_common->context = encoder_sirc; |  | ||||||
|     return encoder_common; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void irda_encoder_sirc_free(void* encoder_ptr) { | void irda_encoder_sirc_free(void* encoder_ptr) { | ||||||
|     IrdaCommonEncoder* encoder = encoder_ptr; |     irda_common_encoder_free(encoder_ptr); | ||||||
|     free(encoder->context); |  | ||||||
|     irda_common_encoder_free(encoder); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| IrdaStatus irda_encoder_sirc_encode(void* encoder_ptr, uint32_t* duration, bool* level) { | IrdaStatus irda_encoder_sirc_encode(void* encoder_ptr, uint32_t* duration, bool* level) { | ||||||
|     IrdaCommonEncoder* encoder_common = encoder_ptr; |     IrdaCommonEncoder* encoder = encoder_ptr; | ||||||
|     IrdaSircEncoder* encoder_sirc = encoder_common->context; |  | ||||||
| 
 | 
 | ||||||
|     IrdaStatus status = irda_common_encode(encoder_ptr, duration, level); |     IrdaStatus status = irda_common_encode(encoder, duration, level); | ||||||
|     if ((status == IrdaStatusOk) && (encoder_common->bits_encoded == encoder_sirc->databits)) { |     if ((status == IrdaStatusOk) && (encoder->bits_encoded == encoder->bits_to_encode)) { | ||||||
|         furi_assert(!*level); |         furi_assert(!*level); | ||||||
|         status = IrdaStatusDone; |         status = IrdaStatusDone; | ||||||
|         encoder_common->state = IrdaCommonEncoderStateEncodeRepeat; |         encoder->state = IrdaCommonEncoderStateEncodeRepeat; | ||||||
|     } |     } | ||||||
|     return status; |     return status; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Albert Kharisov
						Albert Kharisov