From a484b095fb03313f5f192b23c90d04972ca3b957 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 4 Jun 2017 10:00:57 +0200 Subject: o Getting closer to a working decoder. --- include/decoder.h | 26 +++++++++ include/samsung_decoder.h | 38 +++++++++++++ src/radio-controller.cpp | 134 +++++++++++++++++++++++++++++++--------------- thirdparty/mcucpp | 2 +- 4 files changed, 157 insertions(+), 43 deletions(-) create mode 100644 include/decoder.h create mode 100644 include/samsung_decoder.h diff --git a/include/decoder.h b/include/decoder.h new file mode 100644 index 0000000..2a8c58e --- /dev/null +++ b/include/decoder.h @@ -0,0 +1,26 @@ +#pragma once + +namespace radio_controller { + +template +class iterator { +public: + virtual bool next() = 0; + + virtual bool has_next() const = 0; + + virtual const T &value() const = 0; +}; + +struct sample { + uint16_t period_us; + uint16_t pulse_us; +}; + +//template +class decoder { +public: + virtual void decode(iterator *it) = 0; +}; + +} // namespace radio_controller diff --git a/include/samsung_decoder.h b/include/samsung_decoder.h new file mode 100644 index 0000000..5d2b555 --- /dev/null +++ b/include/samsung_decoder.h @@ -0,0 +1,38 @@ +#pragma + +#include "decoder.h" + +namespace radio_controller { + +class samsung_decoder : public decoder { + + inline + bool between(uint16_t smallest, uint16_t biggest, uint16_t value) + { + return smallest <= value && value <= biggest; + } + + inline + bool start_bit(uint16_t time) + { + return between(4200, 4700, time); + } + + inline + bool one_bit(uint16_t time) + { + return between(4200, 4700, time); + } + +public: + void decode(iterator *it) override + { + printf("Samsung\n"); + while (it->next()) { + auto s = it->value(); + printf("% 5d us % 5d us, %.02d%%\n", s.period_us, s.pulse_us, int(s.pulse_us / double(s.period_us) * 100)); + } + } +}; + +} // namespace radio_controller diff --git a/src/radio-controller.cpp b/src/radio-controller.cpp index 8b350d2..d31f5b7 100644 --- a/src/radio-controller.cpp +++ b/src/radio-controller.cpp @@ -5,9 +5,13 @@ #include "mcu/arm/semihosting.h" #include "mcu/stm32cube/uart.h" #include "mcu/stm32cube/debug.h" +#include "mcu/util.h" #include "misc.h" +#include "decoder.h" +#include "samsung_decoder.h" using mcu::arm::mutex; +using namespace radio_controller; extern IWDG_HandleTypeDef hiwdg; extern TIM_HandleTypeDef htim1; @@ -17,9 +21,36 @@ extern UART_HandleTypeDef huart2; mcu::stm32cube::uart::uart_port uart2(&huart2); mcu::stm32cube::debug::dbg<100> dbg(uart2); -struct sample { - uint16_t period_us; - uint16_t pulse_us; +template +class buffer_iterator : public iterator { + const T *values_; + const int size_; + int idx_; + +public: + buffer_iterator(const T *values, int size) : values_(values), size_(size), idx_(-1) + {}; + + __noinline + bool next() override + { + if (has_next()) { + idx_++; + return true; + } + return false; + } + + inline + bool has_next() const override + { + return idx_ < size_ - 1; + }; + + const T &value() const override + { + return values_[idx_]; + } }; template @@ -28,6 +59,7 @@ class buffer { volatile unsigned int size_; + uint32_t start_; bool first_; int part_; @@ -37,6 +69,7 @@ public: size_ = 0; first_ = true; part_ = 1; + start_ = 0; } bool check_first_part() @@ -73,6 +106,12 @@ public: return size_ == BufferSize; } + __always_inline + uint32_t start() const + { + return start_; + } + __always_inline void append(T sample) { @@ -80,6 +119,10 @@ public: return; } + if (size_ == 0) { + start_ = HAL_GetTick(); + } + samples[size_++] = sample; } @@ -88,6 +131,11 @@ public: { return samples[i]; } + + buffer_iterator iterator() + { + return buffer_iterator(this->samples, this->size_); + } }; template @@ -96,7 +144,7 @@ using sample_buffer = buffer; sample_buffer<10> radio_buffer; mutex radio_buffer_lock; -sample_buffer<30> ir_buffer; +sample_buffer<100> ir_buffer; buffer<100, uint16_t> ir_level_buffer; mutex ir_buffer_lock; @@ -137,8 +185,6 @@ void main_post_init() static uint32_t tick_next = 0; -//static bool seen_high = false; - void main_loop() { auto now = HAL_GetTick(); @@ -150,7 +196,6 @@ void main_loop() // CDC_Transmit_FS(const_cast(reinterpret_cast(str)), 5); tick_next += 1000; -// seen_high = false; } if (radio_buffer.is_full()) { @@ -174,27 +219,20 @@ void main_loop() radio_buffer_lock.unlock(); } - /* - if (ir_buffer.is_full()) { + if (ir_buffer.is_full() || (!ir_buffer.is_empty() && now > ir_buffer.start() + 100)) { ir_buffer_lock.lock(); - hal_ok(HAL_TIM_IC_Stop_IT(&htim2, TIM_CHANNEL_1)); - hal_ok(HAL_TIM_IC_Stop_IT(&htim2, TIM_CHANNEL_2)); - dbg.println("IR"); - for (unsigned int i = 0; i < ir_buffer.size(); i++) { - sample s = ir_buffer.at(i); - auto pulse = s.pulse_us; - auto period = s.period_us; - dbg.println("% 5d us % 5d us, %.02d%%", period, pulse, int(pulse / double(period) * 100)); - } - dbg.println(); + HAL_NVIC_DisableIRQ(TIM2_IRQn); + + samsung_decoder d; + auto it = ir_buffer.iterator(); + d.decode(&it); ir_buffer.reset(); - hal_ok(HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1)); - hal_ok(HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2)); ir_buffer_lock.unlock(); + + HAL_NVIC_EnableIRQ(TIM2_IRQn); } - */ if (ir_level_buffer.is_full()) { ir_buffer_lock.lock(); @@ -213,50 +251,61 @@ void main_loop() HAL_NVIC_EnableIRQ(TIM2_IRQn); } -// seen_high |= HAL_GPIO_ReadPin(RADIO_RX_GPIO_Port, RADIO_RX_Pin); - - HAL_IWDG_Refresh(&hiwdg); + __HAL_IWDG_RELOAD_COUNTER(&hiwdg); } -//static uint16_t start = 0; - -uint16_t ir_value1, ir_value2; - static -void ir_rx(TIM_HandleTypeDef *htim) +void ir_rx_level(TIM_HandleTypeDef *htim) { + static uint16_t ir_value1, ir_value2; + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { + ir_value1 = static_cast(htim->Instance->CCR1); debug_pin(2); - } - if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { + } else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { + ir_value2 = static_cast(htim->Instance->CCR2); debug_pin(3); } + if (!ir_level_buffer.check_first()) { + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { + ir_level_buffer.append(values::to_us(ir_value1 - ir_value2)); + } else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { + ir_level_buffer.append(values::to_us(ir_value2)); + } + } +} + +static +void ir_rx(TIM_HandleTypeDef *htim) +{ + static uint16_t ir_value1, ir_value2; + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { ir_value1 = static_cast(htim->Instance->CCR1); + debug_pin(2); } else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { ir_value2 = static_cast(htim->Instance->CCR2); + debug_pin(3); } - if (ir_level_buffer.check_first()) { + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1 && ir_buffer.check_first()) { +// debug_pin(10); return; } if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { - ir_level_buffer.append(values::to_us(ir_value1 - ir_value2)); - } else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { - ir_level_buffer.append(values::to_us(ir_value2)); - } - - /* - if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1 && !ir_buffer.check_first()) { if (ir_buffer_lock.try_lock()) { - ir_buffer.append({values::to_us(ir_value1), values::to_us(ir_value2)}); + auto period = values::to_us(ir_value1); + auto pulse = values::to_us(ir_value2); + if (ir_buffer.size() == 0) { + debug_pin(5); + } + ir_buffer.append({.period_us=period, .pulse_us=pulse}); ir_buffer_lock.unlock(); } } - */ } static @@ -302,5 +351,6 @@ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) } if (htim == &htim2) { ir_rx(htim); +// ir_rx_level(htim); } } diff --git a/thirdparty/mcucpp b/thirdparty/mcucpp index c93636e..36b6a66 160000 --- a/thirdparty/mcucpp +++ b/thirdparty/mcucpp @@ -1 +1 @@ -Subproject commit c93636e804b3c2158c8258de422f0351263e0375 +Subproject commit 36b6a66bf901a4438af96a0c83867937324580c6 -- cgit v1.2.3