From 645fe332f1ba309392e1b148f538343b0ed798a7 Mon Sep 17 00:00:00 2001 From: Puff Machine <13399678+Puff-Machine@users.noreply.github.com> Date: Mon, 25 Nov 2024 10:38:53 +0000 Subject: [PATCH] Encoder for T330 collar (#322) --- include/radio/rmt/T330Encoder.h | 12 ++++++++ src/radio/rmt/T330Encoder.cpp | 50 +++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 include/radio/rmt/T330Encoder.h create mode 100644 src/radio/rmt/T330Encoder.cpp diff --git a/include/radio/rmt/T330Encoder.h b/include/radio/rmt/T330Encoder.h new file mode 100644 index 00000000..aded95e0 --- /dev/null +++ b/include/radio/rmt/T330Encoder.h @@ -0,0 +1,12 @@ +#pragma once + +#include "ShockerCommandType.h" + +#include + +#include +#include + +namespace OpenShock::Rmt::T330Encoder { + std::vector GetSequence(uint16_t transmitterId, OpenShock::ShockerCommandType type, uint8_t intensity); +} diff --git a/src/radio/rmt/T330Encoder.cpp b/src/radio/rmt/T330Encoder.cpp new file mode 100644 index 00000000..d602a342 --- /dev/null +++ b/src/radio/rmt/T330Encoder.cpp @@ -0,0 +1,50 @@ +#include "radio/rmt/T330Encoder.h" + +#include "radio/rmt/internal/Shared.h" + +const rmt_data_t kRmtPreamble = {960, 1, 790, 0}; +const rmt_data_t kRmtOne = {220, 1, 980, 0}; +const rmt_data_t kRmtZero = {220, 1, 580, 0}; +const rmt_data_t kRmtPostamble = {220, 1, 135, 0}; + +using namespace OpenShock; + +std::vector Rmt::T330Encoder::GetSequence(uint16_t transmitterId, ShockerCommandType type, uint8_t intensity) +{ + // Intensity must be between 0 and 100 + intensity = std::min(intensity, static_cast(100)); + + uint8_t typeVal = 0; + switch (type) { + case ShockerCommandType::Shock: + typeVal = 0b01100001; + break; + case ShockerCommandType::Vibrate: + typeVal = 0b01110010; + break; + case ShockerCommandType::Sound: + typeVal = 0b10000100; + intensity = 0; // The remote always sends 0, I don't know what happens if you send something else. + break; + default: + return {}; // Invalid type + } + + uint8_t channelId = 0; // CH1 is 0b0000 and CH2 is 0b1110 on my remote but other values probably work. + + // Payload layout: [channelId:4][typeU:4][transmitterId:16][intensity:8][typeL:4][channelId:4] + uint64_t data = (static_cast(channelId & 0xF) << 36) | (static_cast(typeVal & 0xF0) << 28) | (static_cast(transmitterId) << 16) | (static_cast(intensity) << 8) | (static_cast(typeVal & 0xF) << 4) | static_cast(channelId & 0xF); + + // Shift the data left by 1 bit to append a zero + data <<= 1; + + std::vector pulses; + pulses.reserve(43); + + // Generate the sequence + pulses.push_back(kRmtPreamble); + Internal::EncodeBits<41>(pulses, data, kRmtOne, kRmtZero); + pulses.push_back(kRmtPostamble); + + return pulses; +}