#include "remote.h" #include #include volatile remote_button_t g_remote_button; static int g_num_bits = 99; /* Number of bits received */ volatile uint32_t g_remote_code = 0; /* The code received */ systime_t g_prev_received = 0; /* Decode the codes into button indexes */ static remote_button_t decode_code(uint32_t code) { switch (code) { /* Original remote */ case 0xFF00EF00: return RM_BRIGHTUP; case 0xFE01EF00: return RM_BRIGHTDOWN; case 0xFD02EF00: return RM_OFF; case 0xFC03EF00: return RM_ON; case 0xFB04EF00: return RM_RED; case 0xFA05EF00: return RM_GREEN; case 0xF906EF00: return RM_BLUE; case 0xF807EF00: return RM_WHITE; case 0xF708EF00: return RM_1; case 0xF609EF00: return RM_2; case 0xF50AEF00: return RM_3; case 0xF40BEF00: return RM_SETUP; case 0xF30CEF00: return RM_4; case 0xF20DEF00: return RM_5; case 0xF10EEF00: return RM_6; case 0xF00FEF00: return RM_STROBE; case 0xEF10EF00: return RM_7; case 0xEE11EF00: return RM_8; case 0xED12EF00: return RM_9; case 0xEC13EF00: return RM_FADE; case 0xEB14EF00: return RM_WEND; case 0xEA15EF00: return RM_0; case 0xE916EF00: return RM_WDAY; case 0xE817EF00: return RM_SMOOTH; /* Replacement remote */ case 0xFA05FF00: return RM_BRIGHTUP; case 0xFB04FF00: return RM_BRIGHTDOWN; case 0xF906FF00: return RM_OFF; case 0xF807FF00: return RM_ON; case 0xF609FF00: return RM_RED; case 0xF708FF00: return RM_GREEN; case 0xF50AFF00: return RM_BLUE; case 0xF40BFF00: return RM_WHITE; case 0xF20DFF00: return RM_1; case 0xF30CFF00: return RM_2; case 0xF10EFF00: return RM_3; case 0xF00FFF00: return RM_SETUP; case 0xEA15FF00: return RM_4; case 0xEB14FF00: return RM_5; case 0xE916FF00: return RM_6; case 0xE817FF00: return RM_STROBE; case 0xE619FF00: return RM_7; case 0xE718FF00: return RM_8; case 0xE51AFF00: return RM_9; case 0xE41BFF00: return RM_FADE; case 0xEE11FF00: return RM_WEND; case 0xEF10FF00: return RM_0; case 0xED12FF00: return RM_WDAY; case 0xEC13FF00: return RM_SMOOTH; default: return RM_IDLE; } } /* Called for every input pulse (in interrupt context) */ static void pulse_callback(ICUDriver *icup) { int width = icuGetWidth(icup); if (width > 4000 && width < 5000) { // Start bit g_num_bits = 0; g_remote_code = 0; } else if (width > 2000 && width < 3000) { g_num_bits = 99; // Repeat g_prev_received = chTimeNow(); } else if (width > 1000 && width < 2000) { // '1' bit g_remote_code |= (1 << g_num_bits); g_num_bits++; } else if (width > 300 && width < 800) { // '0' bit g_num_bits++; } else { g_num_bits = 99; // Invalid pulse } if (g_num_bits == 32) { g_remote_button = decode_code(g_remote_code); g_prev_received = chTimeNow(); } } /* Called every 65 ms to check if the button is still down */ static void overflow_cb(ICUDriver *icup) { if (chTimeNow() - g_prev_received > MS2ST(120) && g_remote_code != 0) { g_remote_button = RM_IDLE; g_remote_code = 0; } } static const ICUConfig icucfg = { ICU_INPUT_ACTIVE_HIGH, 1000000, pulse_callback, NULL, overflow_cb, ICU_CHANNEL_1, 0 }; void remote_init() { icuStart(&ICUD2, &icucfg); icuEnable(&ICUD2); }