forked from electro/esp-irblaster
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
3.5 KiB
107 lines
3.5 KiB
/* Hello World Example
|
|
|
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
|
|
|
Unless required by applicable law or agreed to in writing, this
|
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
CONDITIONS OF ANY KIND, either express or implied.
|
|
*/
|
|
#include <stdio.h>
|
|
#include "sdkconfig.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "esp_system.h"
|
|
#include "esp_spi_flash.h"
|
|
#include "driver/ledc.h"
|
|
#include "irblast.h"
|
|
|
|
static portMUX_TYPE mux_irblast;
|
|
|
|
#define CMDLEN 4
|
|
|
|
static const uint8_t COMMANDS[][CMDLEN] = {
|
|
[IRBLAST_ONOFF] = {0b10000000, 0b01111111, 0b00000000, 0b11111111},
|
|
[IRBLAST_DAYNIGHT] = {0b10000000, 0b01111111, 0b10000000, 0b01111111},
|
|
[IRBLAST_SPEED1] = {0b10000000, 0b01111111, 0b10101000, 0b01010111},
|
|
[IRBLAST_SPEED2] = {0b10000000, 0b01111111, 0b01101000, 0b10010111},
|
|
[IRBLAST_SPEED3] = {0b10000000, 0b01111111, 0b00101000, 0b11010111},
|
|
[IRBLAST_MODE1] = {0b10000000, 0b01111111, 0b00011000, 0b11100111},
|
|
[IRBLAST_MODE2] = {0b10000000, 0b01111111, 0b10011000, 0b01100111},
|
|
[IRBLAST_MODE3] = {0b10000000, 0b01111111, 0b00001000, 0b11110111},
|
|
[IRBLAST_MODE4] = {0b10000000, 0b01111111, 0b10001000, 0b01110111},
|
|
[IRBLAST_HUM1] = {0b10000000, 0b01111111, 0b00010000, 0b11101111},
|
|
[IRBLAST_HUM2] = {0b10000000, 0b01111111, 0b01010000, 0b10101111},
|
|
[IRBLAST_HUM3] = {0b10000000, 0b01111111, 0b10010000, 0b01101111},
|
|
};
|
|
|
|
void irblast_setup() {
|
|
vPortCPUInitializeMutex(&mux_irblast);
|
|
|
|
ledc_timer_config_t ledc_timer = {
|
|
.duty_resolution = LEDC_TIMER_8_BIT, // resolution of PWM duty
|
|
.freq_hz = 38500, // frequency of PWM signal
|
|
.speed_mode = LEDC_HIGH_SPEED_MODE, // timer mode
|
|
.timer_num = LEDC_TIMER_0, // timer index
|
|
.clk_cfg = LEDC_AUTO_CLK, // Auto select the source clock
|
|
};
|
|
// Set configuration of timer0 for high speed channels
|
|
ledc_timer_config(&ledc_timer);
|
|
|
|
ledc_channel_config_t chan = {
|
|
.channel = LEDC_CHANNEL_0,
|
|
.duty = 127,
|
|
.gpio_num = CONFIG_PIN_IRLED,
|
|
.speed_mode = LEDC_HIGH_SPEED_MODE,
|
|
.hpoint = 0,
|
|
.timer_sel = LEDC_TIMER_0
|
|
};
|
|
ledc_channel_config(&chan);
|
|
}
|
|
|
|
static inline void pwm_on() {
|
|
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 127);
|
|
ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0);
|
|
}
|
|
|
|
static inline void pwm_off() {
|
|
ledc_stop(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 0);
|
|
}
|
|
|
|
void irblast_send(enum irblast_cmd cmd) {
|
|
const uint8_t *bytes = COMMANDS[cmd];
|
|
|
|
portENTER_CRITICAL(&mux_irblast);
|
|
|
|
// Preamble
|
|
pwm_on();
|
|
ets_delay_us(9000);
|
|
pwm_off();
|
|
ets_delay_us(4500);
|
|
|
|
for (int i = 0; i < CMDLEN; i++) {
|
|
uint8_t byte = bytes[i];
|
|
for (int j = 0; j < 8; j++) {
|
|
if ((byte & 0x80) == 0) {
|
|
pwm_on();
|
|
ets_delay_us(588);
|
|
pwm_off();
|
|
ets_delay_us(540);
|
|
} else {
|
|
pwm_on();
|
|
ets_delay_us(590);
|
|
pwm_off();
|
|
ets_delay_us(1672);
|
|
}
|
|
byte <<= 1;
|
|
}
|
|
}
|
|
|
|
// one "1" at the end, for some reason
|
|
pwm_on();
|
|
ets_delay_us(600);
|
|
pwm_off();
|
|
|
|
portEXIT_CRITICAL(&mux_irblast);
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
}
|
|
|