Skip to content
Permalink
master
Go to file
 
 
Cannot retrieve contributors at this time
372 lines (328 sloc) 9.39 KB
#ifndef OC_AUTOTUNER_H
#define OC_AUTOTUNER_H
#include "OC_autotune.h"
#include "OC_options.h"
#if defined(BUCHLA_4U) && !defined(IO_10V)
const char* const AT_steps[] = {
"0.0V", "1.2V", "2.4V", "3.6V", "4.8V", "6.0V", "7.2V", "8.4V", "9.6V", "10.8V", " "
};
#elif defined(IO_10V)
const char* const AT_steps[] = {
"0.0V", "1.0V", "2.0V", "3.0V", "4.0V", "5.0V", "6.0V", "7.0V", "8.0V", "9.0V", " "
};
#elif defined(VOR)
const char* const AT_steps[] = {
"0.0V", "1.0V", "2.0V", "3.0V", "4.0V", "5.0V", "6.0V", "7.0V", "8.0V", "9.0V", "10.0V", " "
};
#else
const char* const AT_steps[] = {
"-3V", "-2V", "-1V", " 0V", "+1V", "+2V", "+3V", "+4V", "+5V", "+6V", " "
};
#endif
namespace OC {
enum AUTO_MENU_ITEMS {
DATA_SELECT,
AUTOTUNE,
AUTORUN,
AUTO_MENU_ITEMS_LAST
};
enum AT_STATUS {
AT_OFF,
AT_READY,
AT_RUN,
AT_ERROR,
AT_DONE,
AT_LAST,
};
enum AUTO_CALIBRATION_STEP {
DAC_VOLT_0_ARM,
DAC_VOLT_0_BASELINE,
DAC_VOLT_TARGET_FREQUENCIES,
DAC_VOLT_3m,
DAC_VOLT_2m,
DAC_VOLT_1m,
DAC_VOLT_0,
DAC_VOLT_1,
DAC_VOLT_2,
DAC_VOLT_3,
DAC_VOLT_4,
DAC_VOLT_5,
DAC_VOLT_6,
AUTO_CALIBRATION_STEP_LAST
};
template <typename Owner>
class Autotuner {
public:
void Init() {
owner_ = nullptr;
cursor_pos_ = 0;
data_select_ = 0;
channel_ = 0;
calibration_data_ = 0;
auto_tune_running_status_ = 0;
}
bool active() const {
return nullptr != owner_;
}
void Open(Owner *owner) {
owner_ = owner;
channel_ = owner_->get_channel();
Begin();
}
void Close();
void Draw();
void HandleButtonEvent(const UI::Event &event);
void HandleEncoderEvent(const UI::Event &event);
private:
Owner *owner_;
size_t cursor_pos_;
size_t data_select_;
int8_t channel_;
uint8_t calibration_data_;
uint8_t auto_tune_running_status_;
void Begin();
void move_cursor(int offset);
void change_value(int offset);
void handleButtonLeft(const UI::Event &event);
void handleButtonUp(const UI::Event &event);
void handleButtonDown(const UI::Event &event);
};
template <typename Owner>
void Autotuner<Owner>::Draw() {
weegfx::coord_t w = 128;
weegfx::coord_t x = 0;
weegfx::coord_t y = 0;
weegfx::coord_t h = 64;
graphics.clearRect(x, y, w, h);
graphics.drawFrame(x, y, w, h);
graphics.setPrintPos(x + 2, y + 3);
graphics.print(OC::Strings::channel_id[channel_]);
x = 16; y = 15;
if (owner_->autotuner_error()) {
auto_tune_running_status_ = AT_ERROR;
owner_->reset_autotuner();
}
else if (owner_->autotuner_completed()) {
auto_tune_running_status_ = AT_DONE;
owner_->autotuner_reset_completed();
}
for (size_t i = 0; i < (AUTO_MENU_ITEMS_LAST - 0x1); ++i, y += 20) {
//
graphics.setPrintPos(x + 2, y + 4);
if (i == DATA_SELECT) {
graphics.print("use --> ");
switch(calibration_data_) {
case 0x0:
graphics.print("(dflt.)");
break;
case 0x01:
graphics.print("auto.");
break;
default:
graphics.print("dflt.");
break;
}
}
else if (i == AUTOTUNE) {
switch (auto_tune_running_status_) {
//to display progress, if running
case AT_OFF:
graphics.print("run --> ");
graphics.print(" ... ");
break;
case AT_READY: {
graphics.print("arm > ");
float _freq = owner_->get_auto_frequency();
if (_freq == 0.0f)
graphics.printf("wait ...");
else
graphics.printf("%7.3f", _freq);
}
break;
case AT_RUN:
{
int _octave = owner_->get_octave_cnt();
if (_octave > 1 && _octave < OCTAVES) {
for (int i = 0; i <= _octave; i++, x += 6)
graphics.drawBitmap8(x + 18, y + 4, 4, OC::bitmap_indicator_4x8);
}
else if (owner_->auto_tune_step() == DAC_VOLT_0_BASELINE || owner_->auto_tune_step() == DAC_VOLT_TARGET_FREQUENCIES) // this goes too quick, so ...
graphics.print(" 0.0V baseline");
else {
graphics.print(AT_steps[owner_->auto_tune_step() - DAC_VOLT_3m]);
if (!owner_->_ready())
graphics.print(" ");
else
graphics.printf(" > %7.3f", owner_->get_auto_frequency());
}
}
break;
case AT_ERROR:
graphics.print("run --> ");
graphics.print("error!");
break;
case AT_DONE:
graphics.print(OC::Strings::channel_id[channel_]);
graphics.print(" --> a-ok!");
calibration_data_ = owner_->data_available();
break;
default:
break;
}
}
}
x = 16; y = 15;
for (size_t i = 0; i < (AUTO_MENU_ITEMS_LAST - 0x1); ++i, y += 20) {
graphics.drawFrame(x, y, 95, 16);
// cursor:
if (i == cursor_pos_)
graphics.invertRect(x - 2, y - 2, 99, 20);
}
}
template <typename Owner>
void Autotuner<Owner>::HandleButtonEvent(const UI::Event &event) {
if (UI::EVENT_BUTTON_PRESS == event.type) {
switch (event.control) {
case OC::CONTROL_BUTTON_UP:
handleButtonUp(event);
break;
case OC::CONTROL_BUTTON_DOWN:
handleButtonDown(event);
break;
case OC::CONTROL_BUTTON_L:
handleButtonLeft(event);
break;
case OC::CONTROL_BUTTON_R:
owner_->reset_autotuner();
Close();
break;
default:
break;
}
}
else if (UI::EVENT_BUTTON_LONG_PRESS == event.type) {
switch (event.control) {
case OC::CONTROL_BUTTON_UP:
// screensaver
break;
case OC::CONTROL_BUTTON_DOWN:
OC::DAC::reset_all_auto_channel_calibration_data();
calibration_data_ = 0x0;
break;
case OC::CONTROL_BUTTON_L:
break;
case OC::CONTROL_BUTTON_R:
// app menu
break;
default:
break;
}
}
}
template <typename Owner>
void Autotuner<Owner>::HandleEncoderEvent(const UI::Event &event) {
if (OC::CONTROL_ENCODER_R == event.control) {
move_cursor(event.value);
}
else if (OC::CONTROL_ENCODER_L == event.control) {
change_value(event.value);
}
}
template <typename Owner>
void Autotuner<Owner>::move_cursor(int offset) {
if (auto_tune_running_status_ < AT_RUN) {
int cursor_pos = cursor_pos_ + offset;
CONSTRAIN(cursor_pos, 0, AUTO_MENU_ITEMS_LAST - 0x2);
cursor_pos_ = cursor_pos;
//
if (cursor_pos_ == DATA_SELECT)
auto_tune_running_status_ = AT_OFF;
}
else if (auto_tune_running_status_ == AT_ERROR || auto_tune_running_status_ == AT_DONE)
auto_tune_running_status_ = AT_OFF;
}
template <typename Owner>
void Autotuner<Owner>::change_value(int offset) {
switch (cursor_pos_) {
case DATA_SELECT:
{
uint8_t data = owner_->data_available();
if (!data) { // no data --
calibration_data_ = 0x0;
data_select_ = 0x0;
}
else {
int _data_sel = data_select_ + offset;
CONSTRAIN(_data_sel, 0, 0x1);
data_select_ = _data_sel;
if (_data_sel == 0x0) {
calibration_data_ = 0xFF;
owner_->use_default();
}
else {
calibration_data_ = 0x01;
owner_->use_auto_calibration();
}
}
}
break;
case AUTOTUNE:
{
if (auto_tune_running_status_ < AT_RUN) {
int _status = auto_tune_running_status_ + offset;
CONSTRAIN(_status, 0, AT_READY);
auto_tune_running_status_ = _status;
owner_->autotuner_arm(_status);
}
else if (auto_tune_running_status_ == AT_ERROR || auto_tune_running_status_ == AT_DONE)
auto_tune_running_status_ = 0x0;
}
break;
default:
break;
}
}
template <typename Owner>
void Autotuner<Owner>::handleButtonUp(const UI::Event &event) {
if (cursor_pos_ == AUTOTUNE && auto_tune_running_status_ == AT_OFF) {
// arm the tuner
auto_tune_running_status_ = AT_READY;
owner_->autotuner_arm(auto_tune_running_status_);
}
else {
owner_->reset_autotuner();
auto_tune_running_status_ = AT_OFF;
}
}
template <typename Owner>
void Autotuner<Owner>::handleButtonDown(const UI::Event &event) {
if (cursor_pos_ == AUTOTUNE && auto_tune_running_status_ == AT_READY) {
owner_->autotuner_run();
auto_tune_running_status_ = AT_RUN;
}
else if (auto_tune_running_status_ == AT_ERROR) {
owner_->reset_autotuner();
auto_tune_running_status_ = AT_OFF;
}
}
template <typename Owner>
void Autotuner<Owner>::handleButtonLeft(const UI::Event &) {
}
template <typename Owner>
void Autotuner<Owner>::Begin() {
const OC::Autotune_data &autotune_data = OC::AUTOTUNE::GetAutotune_data(channel_);
calibration_data_ = autotune_data.use_auto_calibration_;
if (calibration_data_ == 0x01) // auto cal. data is in use
data_select_ = 0x1;
else
data_select_ = 0x00;
cursor_pos_ = 0x0;
auto_tune_running_status_ = 0x0;
}
template <typename Owner>
void Autotuner<Owner>::Close() {
ui.SetButtonIgnoreMask();
owner_ = nullptr;
}
}; // namespace OC
#endif // OC_AUTOTUNER_H