Created
September 16, 2021 13:14
-
-
Save reeFridge/f49c5edec60a9642cbf7677fd3116f75 to your computer and use it in GitHub Desktop.
ir-receiver-transmitter (esp8266 non-os sdk)
This file contains hidden or 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
#include "osapi.h" | |
#include "user_interface.h" | |
#include "ir_remote.h" | |
static os_timer_t send_impulse_timer; | |
static os_timer_t read_impulse_timer; | |
static os_timer_t enable_interrupt_timer; | |
uint32 ICACHE_FLASH_ATTR user_rf_cal_sector_set(void); | |
#define IR_READ_PIN 14 | |
#define CMD_ONOFF 0xe0e06798 | |
static uint32 current_command = CMD_ONOFF; | |
void enable_interrupt(void) | |
{ | |
gpio_pin_intr_state_set(GPIO_ID_PIN(IR_READ_PIN), GPIO_PIN_INTR_LOLEVEL); | |
} | |
void ICACHE_FLASH_ATTR send_impulse(void) | |
{ | |
gpio_pin_intr_state_set(GPIO_ID_PIN(IR_READ_PIN), GPIO_PIN_INTR_DISABLE); | |
ir_remote_send_samsung(current_command, 32); | |
os_timer_disarm(&enable_interrupt_timer); | |
os_timer_setfn(&enable_interrupt_timer, (os_timer_func_t*)enable_interrupt, (void*)0); | |
os_timer_arm(&enable_interrupt_timer, 500, 0); | |
} | |
uint32 reverse(uint32 x) | |
{ | |
x = ((x >> 1) & 0x55555555u) | ((x & 0x55555555u) << 1); | |
x = ((x >> 2) & 0x33333333u) | ((x & 0x33333333u) << 2); | |
x = ((x >> 4) & 0x0f0f0f0fu) | ((x & 0x0f0f0f0fu) << 4); | |
x = ((x >> 8) & 0x00ff00ffu) | ((x & 0x00ff00ffu) << 8); | |
x = ((x >> 16) & 0xffffu) | ((x & 0xffffu) << 16); | |
return x; | |
} | |
void print_binary(uint32 value, uint32 size) | |
{ | |
for (uint32 i = 0; i < size; ++i) | |
{ | |
uint32 mask = 1 << i; | |
os_printf("%d", (value & mask) >> i); | |
} | |
os_printf("\n"); | |
} | |
#define MAX_COUNT 150 | |
#define TIME_WINDOW 300000 | |
void ICACHE_FLASH_ATTR read_impulse(void) | |
{ | |
os_printf("[DECODE] start\n"); | |
uint32 time = system_get_time(); | |
uint32 signal = 0; | |
uint32 val = 0; | |
uint32 signal_time_start = time; | |
uint32 impulses[MAX_COUNT] = {0}; | |
uint32 count = 0; | |
while ((system_get_time() - time) < TIME_WINDOW && count < MAX_COUNT) | |
{ | |
val = GPIO_INPUT_GET(IR_READ_PIN); | |
if (signal != val) | |
{ | |
uint32 now = system_get_time(); | |
if (val == 0) | |
{ | |
impulses[count++] = now - signal_time_start; | |
signal_time_start = now; | |
} | |
signal = val; | |
} | |
} | |
uint32 buffer = 0; | |
uint32 pos = 0; | |
for (uint32 i = 0; i < MAX_COUNT; ++i) | |
{ | |
uint32 length = impulses[i]; | |
if (i == 0) | |
{ | |
os_printf("HEAD = %d\n", length); | |
} | |
// empty or end | |
if (length > 10000 || length == 0) | |
{ | |
break; | |
} | |
// low (0) | |
if (length > 1000 && length < 2000) | |
{ | |
pos++; | |
continue; | |
} | |
// high (1) | |
if (length > 2000 && length < 3000) | |
{ | |
buffer |= 1 << pos; | |
pos++; | |
continue; | |
} | |
} | |
uint32 address = buffer & 0xFF; | |
uint32 data = (buffer & 0xFF0000) >> 16; | |
uint32 data_inverse = (buffer & 0xFF000000) >> 24; | |
os_printf("ADDRESS:\n"); | |
print_binary(address, 8); | |
os_printf("DATA:\n"); | |
print_binary(data, 8); | |
os_printf("DATA (INVERSE)\n"); | |
print_binary(data_inverse, 8); | |
bool data_verified = data ^ data_inverse; | |
os_printf("VERIFY DATA: %s\n", data_verified ? "PASSED" : "FAILED"); | |
if (data_verified) | |
{ | |
uint32 command = reverse(buffer); | |
os_printf("HEX (LSB->MSB): 0x%04x\n", command); | |
current_command = command; | |
} | |
os_printf("[DECODE] end\n"); | |
} | |
void handle_interruption(void) | |
{ | |
gpio_pin_intr_state_set(GPIO_ID_PIN(IR_READ_PIN), GPIO_PIN_INTR_DISABLE); | |
// called twice but it is ok (maybe figure out why later) | |
os_timer_disarm(&read_impulse_timer); | |
os_timer_setfn(&read_impulse_timer, (os_timer_func_t*)read_impulse, (void*)0); | |
os_timer_arm(&read_impulse_timer, 0, 0); | |
// clear interruption state | |
uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); | |
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status); | |
} | |
void ICACHE_FLASH_ATTR user_init(void) | |
{ | |
gpio_init(); | |
system_set_os_print(1); | |
uart_init(115200, 115200); | |
os_printf("SDK version:%s\n", system_get_sdk_version()); | |
// Disable WiFi | |
wifi_set_opmode(NULL_MODE); | |
ir_remote_init(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4, 4, false); | |
// setting GPIO14 as input | |
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14); | |
GPIO_DIS_OUTPUT(IR_READ_PIN); | |
os_timer_disarm(&send_impulse_timer); | |
os_timer_setfn(&send_impulse_timer, (os_timer_func_t*)send_impulse, (void*)0); | |
os_timer_arm(&send_impulse_timer, 10000, 1); | |
// interruption setup | |
ETS_GPIO_INTR_ENABLE(); | |
ETS_GPIO_INTR_ATTACH((ets_isr_t)(handle_interruption), (void*)0); | |
} | |
uint32 ICACHE_FLASH_ATTR user_rf_cal_sector_set(void) | |
{ | |
enum flash_size_map size_map = system_get_flash_size_map(); | |
uint32 rf_cal_sec = 0; | |
switch (size_map) { | |
case FLASH_SIZE_4M_MAP_256_256: | |
rf_cal_sec = 128 - 5; | |
break; | |
case FLASH_SIZE_8M_MAP_512_512: | |
rf_cal_sec = 256 - 5; | |
break; | |
case FLASH_SIZE_16M_MAP_512_512: | |
case FLASH_SIZE_16M_MAP_1024_1024: | |
rf_cal_sec = 512 - 5; | |
break; | |
case FLASH_SIZE_32M_MAP_512_512: | |
case FLASH_SIZE_32M_MAP_1024_1024: | |
rf_cal_sec = 1024 - 5; | |
break; | |
case FLASH_SIZE_64M_MAP_1024_1024: | |
rf_cal_sec = 2048 - 5; | |
break; | |
case FLASH_SIZE_128M_MAP_1024_1024: | |
rf_cal_sec = 4096 - 5; | |
break; | |
default: | |
rf_cal_sec = 0; | |
break; | |
} | |
return rf_cal_sec; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment