summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2017-06-03 20:47:37 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2017-06-03 20:47:37 +0200
commit0bc2a81c0aab3c89b534415d6f07d07e392260ce (patch)
tree5995a09ea9212df38490b330fc878060b6bb9294 /src
parentdcfb42c972f904482514ef194003018a02c8c260 (diff)
downloadradio-controller-0bc2a81c0aab3c89b534415d6f07d07e392260ce.tar.gz
radio-controller-0bc2a81c0aab3c89b534415d6f07d07e392260ce.tar.bz2
radio-controller-0bc2a81c0aab3c89b534415d6f07d07e392260ce.tar.xz
radio-controller-0bc2a81c0aab3c89b534415d6f07d07e392260ce.zip
o Adding support for reading IR codes.
Diffstat (limited to 'src')
-rw-r--r--src/radio-controller.cpp257
1 files changed, 155 insertions, 102 deletions
diff --git a/src/radio-controller.cpp b/src/radio-controller.cpp
index 0f60717..8b350d2 100644
--- a/src/radio-controller.cpp
+++ b/src/radio-controller.cpp
@@ -5,11 +5,13 @@
#include "mcu/arm/semihosting.h"
#include "mcu/stm32cube/uart.h"
#include "mcu/stm32cube/debug.h"
+#include "misc.h"
using mcu::arm::mutex;
extern IWDG_HandleTypeDef hiwdg;
extern TIM_HandleTypeDef htim1;
+extern TIM_HandleTypeDef htim2;
extern UART_HandleTypeDef huart2;
mcu::stm32cube::uart::uart_port uart2(&huart2);
@@ -20,25 +22,34 @@ struct sample {
uint16_t pulse_us;
};
-template<unsigned int BufferSize>
-class sample_buffer {
- sample samples[BufferSize];
+template<unsigned int BufferSize, typename T>
+class buffer {
+ T samples[BufferSize];
- volatile unsigned int _size;
+ volatile unsigned int size_;
- bool _first;
+ bool first_;
+ int part_;
public:
void reset()
{
- _size = 0;
- _first = true;
+ size_ = 0;
+ first_ = true;
+ part_ = 1;
+ }
+
+ bool check_first_part()
+ {
+ bool first = part_ == 1;
+ part_ = first ? 2 : 1;
+ return first;
}
bool check_first()
{
- if (_first) {
- _first = false;
+ if (first_) {
+ first_ = false;
return true;
}
return false;
@@ -47,35 +58,47 @@ public:
__always_inline
unsigned int size() const
{
- return _size;
+ return size_;
+ }
+
+ __always_inline
+ bool is_empty() const
+ {
+ return size_ == 0;
}
__always_inline
bool is_full() const
{
- return _size == BufferSize;
+ return size_ == BufferSize;
}
__always_inline
- void append(sample sample)
+ void append(T sample)
{
- if (_size == BufferSize) {
+ if (size_ == BufferSize) {
return;
}
- samples[_size++] = sample;
+ samples[size_++] = sample;
}
__always_inline
- sample at(int i) const
+ T at(int i) const
{
return samples[i];
}
};
-volatile int sample_index;
-sample_buffer<10> buffer;
-mutex buffer_lock;
+template<size_t BufferSize>
+using sample_buffer = buffer<BufferSize, sample>;
+
+sample_buffer<10> radio_buffer;
+mutex radio_buffer_lock;
+
+sample_buffer<30> ir_buffer;
+buffer<100, uint16_t> ir_level_buffer;
+mutex ir_buffer_lock;
void main_pre_init()
{
@@ -99,60 +122,23 @@ void main_post_init()
printf("Radio Controller\n");
- buffer.reset();
- sample_index = 0;
+ radio_buffer.reset();
+ radio_buffer_lock.unlock();
+ ir_buffer.reset();
+ ir_level_buffer.reset();
+ ir_buffer_lock.unlock();
uart2.enable();
hal_ok(HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1));
+ hal_ok(HAL_TIM_Base_Start(&htim2));
+ hal_ok(HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1));
+ hal_ok(HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2));
}
static uint32_t tick_next = 0;
//static bool seen_high = false;
-#include <chrono>
-#include <stm32f1xx_hal_tim.h>
-#include <stm32f103x6.h>
-
-template<unsigned Fcpu, typename SecondsPerTimerTick>
-struct from_f_cpu_and_time_per_timer_tick {
- template<std::intmax_t Num, std::intmax_t Den>
- using r = std::ratio<Num, Den>;
-
- using f_cpu = r<Fcpu, 1>;
- using seconds_per_cpu_tick = r<1, f_cpu::num>;
- using seconds_per_timer_tick = SecondsPerTimerTick;
- using timer_frequency = r<SecondsPerTimerTick::den, SecondsPerTimerTick::num>;
-
-// static constexpr std::intmax_t prescaler = std::ratio_divive<f_cpu, timer_frequency>::value;
- using prescaler_t = std::ratio_divide<f_cpu, timer_frequency>;
- static_assert(prescaler_t::den == 1, "Could not represent the prescaler as an integer");
- static constexpr std::intmax_t prescaler = prescaler_t::num;
-
- // us_per_timer_tick = seconds_per_timer_tick * 1'000'000
- using us_per_timer_tick_t = typename std::ratio_multiply<seconds_per_timer_tick, r<1'000'000, 1>>::type;
-
- static constexpr uint16_t us_per_timer_tick = static_cast<uint16_t>(us_per_timer_tick_t::num);
-
- template<typename T>
- __always_inline constexpr
- static T to_us(unsigned int count)
- {
- return T(count * us_per_timer_tick);
- }
-};
-
-using values = from_f_cpu_and_time_per_timer_tick<72'000'000, std::ratio_multiply<std::ratio<5, 1>, std::micro>>;
-
-//static_assert(values::timer_frequency::num == 200'000, "timer_frequency::num");
-static_assert(values::timer_frequency::den == 1, "timer_frequency::den");
-//static_assert(std::is_same<
-// values::timer_frequency,
-// std::ratio<200'000, 1>>::value, "Timer frequency is not 200kHz");
-static_assert(values::prescaler == 360, "Timer frequency is not 200kHz");
-static_assert(values::prescaler - 1 == RADIO_RX_TIMER_PRESCALER, "Bad prescaler from STM32CubeMX");
-static_assert(values::us_per_timer_tick == 5, "bad us_per_timer_tick");
-
void main_loop()
{
auto now = HAL_GetTick();
@@ -167,44 +153,64 @@ void main_loop()
// seen_high = false;
}
- if (buffer.is_full()) {
- buffer_lock.lock();
+ if (radio_buffer.is_full()) {
+ radio_buffer_lock.lock();
hal_ok(HAL_TIM_IC_Stop_IT(&htim1, TIM_CHANNEL_1));
-// printf("Period:");
-// for (unsigned int i = 0; i < buffer.size(); i++) {
-// printf(" %u", buffer.at(i));
-// }
-// printf("\n");
-
-// dbg.print("Pulse: ");
-// for (unsigned int i = 0; i < buffer.size(); i++) {
-// auto p = values::to_us(buffer_pulse.at(i));
-// dbg.print(" %05u", p);
-// }
-// dbg.print("\n");
-//
-// dbg.print("Period:");
-// for (unsigned int i = 0; i < buffer.size(); i++) {
-// auto p = values::to_us(buffer_period.at(i));
-// dbg.print(" %05u", p);
-// }
-// dbg.print("\n");
-
- dbg.println("Samples");
- for (unsigned int i = 0; i < buffer.size(); i++) {
- sample s = buffer.at(i);
+ /*
+ dbg.println("Radio");
+ for (unsigned int i = 0; i < radio_buffer.size(); i++) {
+ sample s = radio_buffer.at(i);
auto pulse = s.pulse_us;
auto period = s.period_us;
- dbg.println("%d %d, %d%%", period, pulse, int(pulse / double(period) * 100));
+ dbg.println("%d us %d us, %d%%", period, pulse, int(pulse / double(period) * 100));
}
dbg.println();
+ */
- buffer.reset();
- sample_index = 0;
+ radio_buffer.reset();
hal_ok(HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1));
- buffer_lock.unlock();
+ radio_buffer_lock.unlock();
+ }
+
+ /*
+ if (ir_buffer.is_full()) {
+ 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();
+
+ 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();
+ }
+ */
+
+ if (ir_level_buffer.is_full()) {
+ ir_buffer_lock.lock();
+
+ HAL_NVIC_DisableIRQ(TIM2_IRQn);
+
+ dbg.println("IR");
+ for (unsigned int i = 0; i < ir_level_buffer.size(); i++) {
+ uint16_t s = ir_level_buffer.at(i);
+ dbg.println("% 5d us", s);
+ }
+ dbg.println();
+
+ ir_level_buffer.reset();
+ ir_buffer_lock.unlock();
+ HAL_NVIC_EnableIRQ(TIM2_IRQn);
}
// seen_high |= HAL_GPIO_ReadPin(RADIO_RX_GPIO_Port, RADIO_RX_Pin);
@@ -214,26 +220,63 @@ void main_loop()
//static uint16_t start = 0;
-void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
+uint16_t ir_value1, ir_value2;
+
+static
+void ir_rx(TIM_HandleTypeDef *htim)
{
- if (htim->Channel != HAL_TIM_ACTIVE_CHANNEL_1) {
+ if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {
+ debug_pin(2);
+ }
+ if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) {
+ debug_pin(3);
+ }
+
+ if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {
+ ir_value1 = static_cast<uint16_t>(htim->Instance->CCR1);
+ } else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) {
+ ir_value2 = static_cast<uint16_t>(htim->Instance->CCR2);
+ }
+
+ if (ir_level_buffer.check_first()) {
return;
}
-// if (buffer.check_first()) {
+ if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {
+ ir_level_buffer.append(values::to_us<uint16_t>(ir_value1 - ir_value2));
+ } else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) {
+ ir_level_buffer.append(values::to_us<uint16_t>(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<uint16_t>(ir_value1), values::to_us<uint16_t>(ir_value2)});
+
+ ir_buffer_lock.unlock();
+ }
+ }
+ */
+}
+
+static
+void radio_rx(TIM_HandleTypeDef *htim)
+{
+ if (htim->Channel != HAL_TIM_ACTIVE_CHANNEL_1) {
+ return;
+ }
+// if (radio_buffer.check_first()) {
// return;
// }
static uint16_t value1, value2;
- if (sample_index == 0) {
+ if (radio_buffer.check_first_part()) {
// value1 = static_cast<uint16_t>(HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1));
value1 = static_cast<uint16_t>(htim->Instance->CCR1);
- sample_index = 1;
} else {
// value2 = static_cast<uint16_t>(HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1));
- value2 = static_cast<uint16_t>(htim->Instance->CCR1);
- sample_index = 0;
+ value2 = static_cast<uint16_t>(htim->Instance->CCR2);
uint16_t diff;
if (value2 > value1) {
@@ -244,10 +287,20 @@ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
return;
}
- if (buffer_lock.try_lock()) {
- buffer.append({values::to_us<uint16_t>(0), values::to_us<uint16_t>(diff)});
+ if (radio_buffer_lock.try_lock()) {
+ radio_buffer.append({values::to_us<uint16_t>(0), values::to_us<uint16_t>(diff)});
- buffer_lock.unlock();
+ radio_buffer_lock.unlock();
}
}
}
+
+void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
+{
+ if (htim == &htim1) {
+ radio_rx(htim);
+ }
+ if (htim == &htim2) {
+ ir_rx(htim);
+ }
+}