-
-
Save notpike/177dddae91b2237dfc75ba810d04a641 to your computer and use it in GitHub Desktop.
NEC Encoder in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// By: NotPike | |
// NEC Encoding | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <string.h> | |
// Varibals | |
#define LEN 16 //Bytes | |
// Commands | |
const uint8_t commands[32] = { | |
0x32, // Pause | |
0x78, // On/Off | |
0x70, // P1 | |
0x60, // P2 | |
0xCA, // P3 SKIP | |
0x20, // F1 | |
0xF2, // Up | |
0xA0, // F2 | |
0x84, // Left | |
0x44, // OK | |
0xC4, // Right | |
0x30, // F3 | |
0x80, // Down | |
0xB0, // F4 | |
0xF0, // 1 | |
0x08, // 2 | |
0x88, // 3 | |
0x48, // 4 | |
0xC8, // 5 | |
0x28, // 6 | |
0xA8, // 7 | |
0x68, // 8 | |
0xE8, // 9 | |
0x18, // Music_Karaoke | |
0x98, // 0 | |
0x58, // Lock_Queue | |
0xD0, // Zone 1 Vol+ | |
0x90, // Zone 2 Vol+ | |
0xC0, // Zone 3 Vol+ | |
0x50, // Zone 1 Vol- | |
0x10, // Zone 2 Vol- | |
0x40, // Zone 3 Vol- | |
}; | |
// Function Refered From Furrtek's Havoc Port | |
// https://github.com/furrtek/portapack-havoc/blob/master/firmware/application/apps/ui_touchtunes.cpp#L75 | |
void encode(char *out, uint8_t command, int pin) { | |
// Variables | |
size_t bit; // Bit counter | |
uint64_t decodeMsg = 0x5D; // Sync Word + decoded value | |
uint8_t encodeMsg; // Bit holder before encoded values are moved to *out | |
// Preamble 0xFFFF00 | |
out[0] = 0xFF; | |
out[1] = 0xFF; | |
out[2] = 0x00; | |
// PIN, LSB First | |
for (bit = 0; bit < 8; bit++) { | |
decodeMsg <<= 1; // Shift left 1 bit | |
if(pin & (1 << bit)) { // If both bits line up add 1 | |
decodeMsg |= 1; | |
} | |
} | |
// Command and it's complement | |
decodeMsg <<= 16; // Shift left 16 bits | |
decodeMsg |= (command << 8); // Add command shift left 8 bits | |
decodeMsg |= (command ^ 0xff); // Add command's complement | |
// NEC Encode | |
size_t bitSize = 0; // Size counter for encodeMsg | |
int arrayPos = 3; // Pointer counter for *out | |
for(bit = 0; bit < (8 + 8 + 16); bit++) { // Sync + Pin + Command == 32bit | |
if(decodeMsg & 0x80000000UL) { // If 1 | |
if(bitSize <= 4) { | |
encodeMsg <<= 4; | |
encodeMsg |= 0x8; // 1000 | |
decodeMsg <<= 1; | |
bitSize += 4; | |
} else if(bitSize == 6) { // Split the Byte | |
encodeMsg <<= 2; | |
encodeMsg |= 0x2; | |
out[arrayPos] = encodeMsg; // Add Byte to char array | |
arrayPos++; | |
encodeMsg <<= 8; // Wipe the stack | |
decodeMsg <<= 1; | |
bitSize = 2; | |
} else if(bitSize == 8) { | |
out[arrayPos] = encodeMsg; // Add Byte to char array | |
arrayPos++; | |
encodeMsg <<= 8; // Wipe the stack | |
encodeMsg |= 0x8; // 1000 | |
decodeMsg <<= 1; | |
bitSize = 4; | |
} | |
} else { // Else 0 | |
if(bitSize <=6) { | |
encodeMsg <<= 2; | |
encodeMsg |= 0x2; // 10 | |
decodeMsg <<= 1; | |
bitSize += 2; | |
} else if(bitSize == 8) { | |
out[arrayPos] = encodeMsg; // Add Byte to char array | |
arrayPos++; | |
encodeMsg <<= 8; // Wipe the stack | |
encodeMsg |= 0x2; // 10 | |
decodeMsg <<= 1; | |
bitSize = 2; | |
} | |
} | |
} | |
// Add Tail | |
if(bitSize == 2) { | |
encodeMsg <<= 4; | |
encodeMsg |= 0x8; // 1000 | |
encodeMsg <<= 2; | |
} else if(bitSize == 4) { | |
encodeMsg <<= 4; | |
encodeMsg |= 0x8; // 1000 | |
} else if(bitSize == 6) { // Split the Byte | |
encodeMsg <<= 2; | |
encodeMsg |= 0x2; // 10 | |
out[arrayPos] = encodeMsg; // Add Byte to char array | |
arrayPos++; | |
encodeMsg <<= 8; // Wipe the stack | |
} else if(bitSize == 8) { | |
out[arrayPos] = encodeMsg; // Add Byte to char array | |
arrayPos++; | |
encodeMsg <<= 8; // Wipe the stack | |
} | |
// Pad with 0x00 if msg length is not 16 Bytes | |
if(arrayPos == 14) { | |
out[14] = encodeMsg; | |
out[15] = 0x00; | |
out[16] = '\0'; | |
} else { | |
out[15] = 0x00; | |
out[16] = '\0'; | |
} | |
} | |
// Known values for PIN 000 | |
static const char * const button_array[] = { | |
"\xff\xff\x00\xa2\x88\x8a\x2a\xaa\xa2\x2a\x28\xaa\x22\x8a\x20\x00",// Skip | |
"\xff\xff\x00\xa2\x88\x8a\x2a\xaa\xaa\x22\xa2\x88\xa8\x8a\x20\x00",// Pause | |
"\xff\xff\x00\xa2\x88\x8a\x2a\xaa\xa2\xaa\xaa\x22\x22\x22\x20\x00",// Down Arrow | |
"\xff\xff\x00\xa2\x88\x8a\x2a\xaa\xa8\xa2\x2a\x8a\x2a\x22\x20\x00",// Lock Queue | |
"\xff\xff\x00\xa2\x88\x8a\x2a\xaa\xa2\xaa\x2a\x88\x88\xa2\x20\x00",// Left Arrow | |
"\xff\xff\x00\xa2\x88\x8a\x2a\xaa\xa8\xaa\x2a\x28\x88\xa2\x20\x00",// OK | |
"\xff\xff\x00\xa2\x88\x8a\x2a\xaa\xa2\x2a\x8a\xa8\x88\xa2\x20\x00",// Right Arrow | |
"\xff\xff\x00\xa2\x88\x8a\x2a\xaa\xa8\x88\x8a\xa2\xaa\x22\x20\x00",// Power | |
"\xff\xff\x00\xa2\x88\x8a\x2a\xaa\xa2\x22\x2a\x2a\xa8\x8a\x20\x00",// Up Arrow | |
"\xff\xff\x00\xa2\x88\x8a\x2a\xaa\xa8\x8a\xaa\x2a\x22\x22\x20\x00" // Edit Queue | |
}; | |
void main() { | |
// Variables | |
static char *list[32]; | |
unsigned char returnValue[17]; | |
uint8_t msg[16] = {0xFF, 0xFF, 0x00, 0xa2, 0x88, 0x8a, 0x2a, 0xaa, // Skip | |
0xa2, 0x2a, 0x28, 0xaa, 0x22, 0x8a, 0x20, 0x00}; | |
uint8_t msg2[16] = {0xFF, 0xFF, 0x00, 0xa2, 0x88, 0x8a, 0x2a, 0xaa, // Edit Queue | |
0xa8, 0x8a, 0xaa, 0x2a, 0x22, 0x22, 0x20, 0x00}; | |
// TEST 1 | |
printf("===Test 1 Skip for PIN 000===\n"); | |
encode(returnValue, commands[4], 0); | |
// Step each char and cmp to msg | |
int ji; | |
for(ji =0; ji < 16; ji++) { | |
if(msg[ji] == returnValue[ji]) { | |
printf("char %i pass\n",ji); | |
} else { | |
printf("char %i fail\n",ji); | |
} | |
} | |
// TEST 2 | |
printf("\n===Test 2 Edit Que for PIN 000===\n"); | |
encode(returnValue, commands[3], 0); | |
// Step each char and cmp to msg2 | |
for(ji =0; ji < 16; ji++) { | |
if(msg2[ji] == returnValue[ji]) { | |
printf("char %i pass\n",ji); | |
} else { | |
printf("char %i fail\n",ji); | |
} | |
} | |
// TEST 3 | |
// Encode all 32 Commands and 256 PINs | |
printf("\n==Test 3 Encode All 32 Commands and 256 PINs==\n"); | |
int xx; | |
for(xx=0; xx < 255; xx++) { | |
int j; | |
for(j = 0; j < 32; j +=1) { | |
encode(returnValue, commands[j], xx); | |
//printf("Command:%i PIN:%i pass\n", j,xx); | |
} | |
} | |
printf("Complete\n"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment