fixed sample rate issues; up to 88kS/s

pull/3/head
Clyne 4 years ago
parent 2238eac451
commit 27060ea3c8

@ -63,10 +63,10 @@
#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK #define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
#define STM32_MCOPRE STM32_MCOPRE_DIV1 #define STM32_MCOPRE STM32_MCOPRE_DIV1
#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK #define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK
#define STM32_PLLSAI1N_VALUE 72 #define STM32_PLLSAI1N_VALUE 44
#define STM32_PLLSAI1P_VALUE 7 #define STM32_PLLSAI1P_VALUE 7
#define STM32_PLLSAI1Q_VALUE 6 #define STM32_PLLSAI1Q_VALUE 6
#define STM32_PLLSAI1R_VALUE 6 #define STM32_PLLSAI1R_VALUE 8
#define STM32_PLLSAI2N_VALUE 72 #define STM32_PLLSAI2N_VALUE 72
#define STM32_PLLSAI2P_VALUE 7 #define STM32_PLLSAI2P_VALUE 7
#define STM32_PLLSAI2R_VALUE 6 #define STM32_PLLSAI2R_VALUE 6
@ -88,7 +88,7 @@
#define STM32_SAI1SEL STM32_SAI1SEL_OFF #define STM32_SAI1SEL STM32_SAI1SEL_OFF
#define STM32_SAI2SEL STM32_SAI2SEL_OFF #define STM32_SAI2SEL STM32_SAI2SEL_OFF
#define STM32_CLK48SEL STM32_CLK48SEL_MSI #define STM32_CLK48SEL STM32_CLK48SEL_MSI
#define STM32_ADCSEL STM32_ADCSEL_SYSCLK #define STM32_ADCSEL STM32_ADCSEL_PLLSAI1
#define STM32_SWPMI1SEL STM32_SWPMI1SEL_PCLK1 #define STM32_SWPMI1SEL STM32_SWPMI1SEL_PCLK1
#define STM32_DFSDMSEL STM32_DFSDMSEL_PCLK2 #define STM32_DFSDMSEL STM32_DFSDMSEL_PCLK2
#define STM32_RTCSEL STM32_RTCSEL_LSI #define STM32_RTCSEL STM32_RTCSEL_LSI
@ -148,8 +148,10 @@
#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5 #define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5
#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5 #define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5
#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5 #define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5
#define STM32_ADC_ADC123_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1 #define STM32_ADC_ADC123_CLOCK_MODE ADC_CCR_CKMODE_ADCCK
#define STM32_ADC_ADC123_PRESC ADC_CCR_PRESC_DIV2 #define STM32_ADC_ADC123_PRESC ADC_CCR_PRESC_DIV10
//#define ADC123_PRESC_VALUE 1
/* /*
* CAN driver system settings. * CAN driver system settings.

@ -5,12 +5,10 @@
#include <wx/menu.h> #include <wx/menu.h>
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/statusbr.h>
enum Id { enum Id {
Single = 1, MeasureTimer = 1,
ConnectDevice,
UploadFilter,
RenderTimer,
MFileNew, MFileNew,
MFileOpen, MFileOpen,
@ -27,6 +25,10 @@ enum Id {
MainFrame::MainFrame() : wxFrame(nullptr, -1, "stmdspgui", wxPoint(50, 50), wxSize(640, 800)) MainFrame::MainFrame() : wxFrame(nullptr, -1, "stmdspgui", wxPoint(50, 50), wxSize(640, 800))
{ {
m_status_bar = new wxStatusBar(this);
m_status_bar->SetStatusText("Ready.");
SetStatusBar(m_status_bar);
auto menubar = new wxMenuBar; auto menubar = new wxMenuBar;
auto menuFile = new wxMenu; auto menuFile = new wxMenu;
Bind(wxEVT_MENU, &MainFrame::onFileNew, this, Id::MFileNew, wxID_ANY, Bind(wxEVT_MENU, &MainFrame::onFileNew, this, Id::MFileNew, wxID_ANY,
@ -46,9 +48,7 @@ MainFrame::MainFrame() : wxFrame(nullptr, -1, "stmdspgui", wxPoint(50, 50), wxSi
menuRun->AppendSeparator(); menuRun->AppendSeparator();
Bind(wxEVT_MENU, &MainFrame::onRunStart, this, Id::MRunStart, wxID_ANY, Bind(wxEVT_MENU, &MainFrame::onRunStart, this, Id::MRunStart, wxID_ANY,
menuRun->Append(MRunStart, "&Start")); menuRun->Append(MRunStart, "&Start"));
m_run_measure = menuRun->AppendCheckItem(MRunMeasure, "&Measure code speed"); m_run_measure = menuRun->AppendCheckItem(MRunMeasure, "&Measure code time");
m_run_measure_value = menuRun->Append(wxID_ANY, "Last time:");
m_run_measure_value->Enable(false);
menuRun->AppendSeparator(); menuRun->AppendSeparator();
Bind(wxEVT_MENU, &MainFrame::onRunCompile, this, Id::MRunCompile, wxID_ANY, Bind(wxEVT_MENU, &MainFrame::onRunCompile, this, Id::MRunCompile, wxID_ANY,
menuRun->Append(MRunCompile, "&Compile code")); menuRun->Append(MRunCompile, "&Compile code"));
@ -67,54 +67,18 @@ MainFrame::MainFrame() : wxFrame(nullptr, -1, "stmdspgui", wxPoint(50, 50), wxSi
prepareEditor(); prepareEditor();
window->Add(m_text_editor, 1, wxEXPAND | wxALL, 10); window->Add(m_text_editor, 1, wxEXPAND | wxALL, 10);
//m_signal_area = new wxControl(this, wxID_ANY, wxDefaultPosition, wxSize(600, 200));
//window->Add(m_signal_area, 1, wxEXPAND | wxALL, 10);
SetSizerAndFit(window); SetSizerAndFit(window);
//m_render_timer = new wxTimer(this, Id::RenderTimer); m_measure_timer = new wxTimer(this, Id::MeasureTimer);
Bind(wxEVT_TIMER, &MainFrame::onMeasureTimer, this, Id::MeasureTimer);
//Bind(wxEVT_PAINT, &MainFrame::onPaint, this, wxID_ANY);
//Bind(wxEVT_TIMER, &MainFrame::onRenderTimer, this, Id::RenderTimer);
}
void MainFrame::onPaint([[maybe_unused]] wxPaintEvent& pe)
{
auto *dc = new wxClientDC(this);
auto region = m_signal_area->GetRect();
dc->SetClippingRegion(region);
dc->SetBrush(*wxBLACK_BRUSH); dc->SetPen(*wxBLACK_PEN);
dc->DrawRectangle(region);
if (m_device_samples.size() > 0) {
dc->SetPen(*wxRED_PEN);
auto points = new wxPoint[m_device_samples.size()];
const float spacing = static_cast<float>(region.GetWidth()) / m_device_samples.size();
float x = 0;
for (auto ptr = points; auto sample : m_device_samples) {
*ptr++ = wxPoint {
static_cast<int>(x),
region.GetHeight() - sample * region.GetHeight() / 4096
};
x += spacing;
}
dc->DrawLines(m_device_samples.size(), points, region.GetX(), region.GetY());
delete[] points;
}
} }
void MainFrame::onRenderTimer([[maybe_unused]] wxTimerEvent& te) void MainFrame::onMeasureTimer([[maybe_unused]] wxTimerEvent&)
{ {
updateDrawing(); if (m_status_bar && m_device) {
m_status_bar->SetStatusText(wxString::Format(wxT("Execution time: %u cycles"),
m_device->continuous_start_get_measurement()));
} }
void MainFrame::updateDrawing()
{
if (m_device_samples = m_device_samples_future.get(); m_device_samples.size() > 0)
this->RefreshRect(m_signal_area->GetRect());
requestSamples();
} }
void MainFrame::prepareEditor() void MainFrame::prepareEditor()
@ -146,7 +110,7 @@ void MainFrame::prepareEditor()
// a sample list of keywords, I haven't included them all to keep it short... // a sample list of keywords, I haven't included them all to keep it short...
m_text_editor->SetKeyWords(0, m_text_editor->SetKeyWords(0,
wxT("return for while do break continue if else goto")); wxT("return for while do break continue if else goto asm"));
m_text_editor->SetKeyWords(1, m_text_editor->SetKeyWords(1,
wxT("void char short int long auto float double unsigned signed " wxT("void char short int long auto float double unsigned signed "
"volatile static const constexpr constinit consteval " "volatile static const constexpr constinit consteval "
@ -205,11 +169,14 @@ wxString MainFrame::compileEditorCode()
wxString make_command = wxString("make -C ") + temp_file_name.BeforeLast('/') + wxString make_command = wxString("make -C ") + temp_file_name.BeforeLast('/') +
" -f " + temp_file_name + "make"; " -f " + temp_file_name + "make";
if (system(make_command.ToAscii()) == 0) if (system(make_command.ToAscii()) == 0) {
m_status_bar->SetStatusText("Compilation succeeded.");
return temp_file_name + ".o"; return temp_file_name + ".o";
else } else {
m_status_bar->SetStatusText("Compilation failed.");
return ""; return "";
} }
}
void MainFrame::onFileNew([[maybe_unused]] wxCommandEvent&) void MainFrame::onFileNew([[maybe_unused]] wxCommandEvent&)
{ {
@ -221,6 +188,7 @@ R"cpp(adcsample_t *process_data(adcsample_t *samples, unsigned int size)
} }
)cpp"); )cpp");
m_text_editor->DiscardEdits(); m_text_editor->DiscardEdits();
m_status_bar->SetStatusText("Ready.");
} }
void MainFrame::onFileOpen([[maybe_unused]] wxCommandEvent&) void MainFrame::onFileOpen([[maybe_unused]] wxCommandEvent&)
@ -237,6 +205,7 @@ void MainFrame::onFileOpen([[maybe_unused]] wxCommandEvent&)
m_open_file_path = openDialog.GetPath(); m_open_file_path = openDialog.GetPath();
m_text_editor->SetText(buffer); m_text_editor->SetText(buffer);
m_text_editor->DiscardEdits(); m_text_editor->DiscardEdits();
m_status_bar->SetStatusText("Ready.");
} }
delete[] buffer; delete[] buffer;
} }
@ -253,8 +222,13 @@ void MainFrame::onFileSave(wxCommandEvent& ce)
file.Write(m_text_editor->GetText()); file.Write(m_text_editor->GetText());
file.Close(); file.Close();
m_text_editor->DiscardEdits(); m_text_editor->DiscardEdits();
m_status_bar->SetStatusText("Saved.");
} else {
m_status_bar->SetStatusText("Save failed: couldn't open file.");
} }
} }
} else {
m_status_bar->SetStatusText("No modifications to save.");
} }
} }
@ -271,8 +245,13 @@ void MainFrame::onFileSaveAs([[maybe_unused]] wxCommandEvent& ce)
file.Close(); file.Close();
m_text_editor->DiscardEdits(); m_text_editor->DiscardEdits();
m_open_file_path = saveDialog.GetPath(); m_open_file_path = saveDialog.GetPath();
m_status_bar->SetStatusText("Saved.");
} else {
m_status_bar->SetStatusText("Save failed: couldn't open file.");
} }
} }
} else {
m_status_bar->SetStatusText("No modifications to save.");
} }
} }
@ -291,16 +270,21 @@ void MainFrame::onRunConnect(wxCommandEvent& ce)
m_device = new stmdsp::device(devices.front()); m_device = new stmdsp::device(devices.front());
if (m_device->connected()) { if (m_device->connected()) {
menuItem->SetItemLabel("&Disconnect"); menuItem->SetItemLabel("&Disconnect");
m_status_bar->SetStatusText("Connected.");
} else { } else {
delete m_device; delete m_device;
m_device = nullptr; m_device = nullptr;
menuItem->SetItemLabel("&Connect"); menuItem->SetItemLabel("&Connect");
m_status_bar->SetStatusText("Failed to connect.");
} }
} else {
m_status_bar->SetStatusText("No devices found.");
} }
} else { } else {
delete m_device; delete m_device;
m_device = nullptr; m_device = nullptr;
menuItem->SetItemLabel("&Connect"); menuItem->SetItemLabel("&Connect");
m_status_bar->SetStatusText("Disconnected.");
} }
} }
@ -308,30 +292,28 @@ void MainFrame::onRunStart(wxCommandEvent& ce)
{ {
auto menuItem = dynamic_cast<wxMenuItem *>(ce.GetEventUserData()); auto menuItem = dynamic_cast<wxMenuItem *>(ce.GetEventUserData());
if (!m_render_timer->IsRunning()) { if (!m_is_running) {
if (m_device != nullptr && m_device->connected()) { if (m_device != nullptr && m_device->connected()) {
if (m_run_measure && m_run_measure->IsChecked()) if (m_run_measure && m_run_measure->IsChecked()) {
m_device->continuous_start_measure(); m_device->continuous_start_measure();
else m_measure_timer->StartOnce(1000);
} else {
m_device->continuous_start(); m_device->continuous_start();
}
m_device_samples_future = std::async(std::launch::async,
[]() { return decltype(m_device_samples)(); });
m_render_timer->Start(1000);
menuItem->SetItemLabel("&Stop"); menuItem->SetItemLabel("&Stop");
m_status_bar->SetStatusText("Running.");
m_is_running = true;
} else { } else {
wxMessageBox("No device connected!", "Run", wxICON_WARNING); wxMessageBox("No device connected!", "Run", wxICON_WARNING);
m_status_bar->SetStatusText("Please connect.");
} }
} else { } else {
m_render_timer->Stop();
m_device->continuous_stop(); m_device->continuous_stop();
menuItem->SetItemLabel("&Start"); menuItem->SetItemLabel("&Start");
if (m_run_measure && m_run_measure_value) { m_status_bar->SetStatusText("Ready.");
m_run_measure_value->SetItemLabel( m_is_running = false;
m_run_measure->IsChecked() ? wxString::Format(wxT("Last time: %u"),m_device->continuous_start_get_measurement())
: "Last time: --");
}
} }
} }
@ -349,22 +331,24 @@ void MainFrame::onRunUpload([[maybe_unused]] wxCommandEvent&)
if (m_device != nullptr && m_device->connected()) { if (m_device != nullptr && m_device->connected()) {
file_stream.ReadAll(buffer, size); file_stream.ReadAll(buffer, size);
m_device->upload_filter(buffer, size); m_device->upload_filter(buffer, size);
m_status_bar->SetStatusText("Code uploaded.");
} else { } else {
wxMessageBox("No device connected!", "Run", wxICON_WARNING); wxMessageBox("No device connected!", "Run", wxICON_WARNING);
m_status_bar->SetStatusText("Please connect.");
} }
} else {
m_status_bar->SetStatusText("Couldn't load compiled code.");
} }
} }
} }
void MainFrame::onRunUnload([[maybe_unused]] wxCommandEvent&) void MainFrame::onRunUnload([[maybe_unused]] wxCommandEvent&)
{ {
if (m_device != nullptr && m_device->connected()) if (m_device != nullptr && m_device->connected()) {
m_device->unload_filter(); m_device->unload_filter();
m_status_bar->SetStatusText("Unloaded code.");
} else {
m_status_bar->SetStatusText("No device connected.");
} }
void MainFrame::requestSamples()
{
m_device_samples_future = std::async(std::launch::async,
[this]() { return m_device->continuous_read(); });
} }

@ -21,9 +21,6 @@ class MainFrame : public wxFrame
public: public:
MainFrame(); MainFrame();
void onPaint(wxPaintEvent& pe);
void onRenderTimer(wxTimerEvent& te);
void onFileNew(wxCommandEvent&); void onFileNew(wxCommandEvent&);
void onFileOpen(wxCommandEvent&); void onFileOpen(wxCommandEvent&);
void onFileSave(wxCommandEvent&); void onFileSave(wxCommandEvent&);
@ -36,22 +33,19 @@ public:
void onRunUpload(wxCommandEvent&); void onRunUpload(wxCommandEvent&);
void onRunUnload(wxCommandEvent&); void onRunUnload(wxCommandEvent&);
void requestSamples(); void onMeasureTimer(wxTimerEvent& te);
void updateDrawing();
private: private:
bool m_is_rendering = false; bool m_is_running = false;
wxTimer *m_render_timer = nullptr;
wxComboBox *m_device_combo = nullptr; wxComboBox *m_device_combo = nullptr;
wxStyledTextCtrl *m_text_editor = nullptr; wxStyledTextCtrl *m_text_editor = nullptr;
wxControl *m_signal_area = nullptr; wxControl *m_signal_area = nullptr;
wxMenuItem *m_run_measure = nullptr; wxMenuItem *m_run_measure = nullptr;
wxMenuItem *m_run_measure_value = nullptr; wxTimer *m_measure_timer = nullptr;
wxStatusBar *m_status_bar = nullptr;
wxString m_open_file_path; wxString m_open_file_path;
stmdsp::device *m_device = nullptr; stmdsp::device *m_device = nullptr;
std::future<std::vector<stmdsp::adcsample_t>> m_device_samples_future;
std::vector<stmdsp::adcsample_t> m_device_samples;
bool tryDevice(); bool tryDevice();
void prepareEditor(); void prepareEditor();

@ -29,7 +29,7 @@ static ADCConversionGroup adc_group_config = {
.cfgr2 = 0, .cfgr2 = 0,
.tr1 = ADC_TR(0, 4095), .tr1 = ADC_TR(0, 4095),
.smpr = { .smpr = {
ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_2P5), 0 ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_12P5), 0
}, },
.sqr = { .sqr = {
ADC_SQR1_SQ1_N(ADC_CHANNEL_IN5), ADC_SQR1_SQ1_N(ADC_CHANNEL_IN5),
@ -38,7 +38,7 @@ static ADCConversionGroup adc_group_config = {
}; };
constexpr static const GPTConfig gpt_config = { constexpr static const GPTConfig gpt_config = {
.frequency = 600000, .frequency = 8000000,
.callback = nullptr, .callback = nullptr,
.cr2 = TIM_CR2_MMS_1, /* TRGO */ .cr2 = TIM_CR2_MMS_1, /* TRGO */
.dier = 0 .dier = 0
@ -65,7 +65,7 @@ namespace adc
adc_is_read_finished = false; adc_is_read_finished = false;
adc_group_config.circular = false; adc_group_config.circular = false;
adcStartConversion(adcd, &adc_group_config, buffer, count); adcStartConversion(adcd, &adc_group_config, buffer, count);
gptStartContinuous(gptd, 5); gptStartContinuous(gptd, 2);
while (!adc_is_read_finished); while (!adc_is_read_finished);
return buffer; return buffer;
} }
@ -77,7 +77,7 @@ namespace adc
adc_operation_func = operation_func; adc_operation_func = operation_func;
adc_group_config.circular = true; adc_group_config.circular = true;
adcStartConversion(adcd, &adc_group_config, buffer, count); adcStartConversion(adcd, &adc_group_config, buffer, count);
gptStartContinuous(gptd, 5); gptStartContinuous(gptd, 2);
} }
void read_set_operation_func(operation_t operation_func) void read_set_operation_func(operation_t operation_func)
@ -113,7 +113,7 @@ namespace adc
val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_24P5); val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_24P5);
break; break;
case rate::R47P5: case rate::R47P5:
val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_47P5); val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_47P5);////
break; break;
case rate::R92P5: case rate::R92P5:
val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_92P5); val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_92P5);

@ -28,7 +28,7 @@ constexpr static const DACConversionGroup dac_group_config = {
}; };
constexpr static const GPTConfig gpt_config = { constexpr static const GPTConfig gpt_config = {
.frequency = 600000, .frequency = 440000,
.callback = nullptr, .callback = nullptr,
.cr2 = TIM_CR2_MMS_1, /* TRGO */ .cr2 = TIM_CR2_MMS_1, /* TRGO */
.dier = 0 .dier = 0

@ -19,7 +19,7 @@
#include <array> #include <array>
constexpr unsigned int MAX_SAMPLE_BUFFER_SIZE = 2048; constexpr unsigned int MAX_SAMPLE_BUFFER_SIZE = 8000;//2048;
enum class RunStatus : char enum class RunStatus : char
{ {
@ -54,7 +54,7 @@ CC_ALIGN(CACHE_LINE_SIZE)
#endif #endif
static std::array<dacsample_t, CACHE_SIZE_ALIGN(dacsample_t, MAX_SAMPLE_BUFFER_SIZE)> dac_samples; static std::array<dacsample_t, CACHE_SIZE_ALIGN(dacsample_t, MAX_SAMPLE_BUFFER_SIZE)> dac_samples;
static uint8_t elf_file_store[8192]; static uint8_t elf_file_store[12288];
static elf::entry_t elf_entry = nullptr; static elf::entry_t elf_entry = nullptr;
static void signal_operate(adcsample_t *buffer, size_t count); static void signal_operate(adcsample_t *buffer, size_t count);
@ -161,6 +161,8 @@ void main_loop()
if (unsigned int binarySize = cmd[1] | (cmd[2] << 8); binarySize < sizeof(elf_file_store)) { if (unsigned int binarySize = cmd[1] | (cmd[2] << 8); binarySize < sizeof(elf_file_store)) {
usbserial::read(elf_file_store, binarySize); usbserial::read(elf_file_store, binarySize);
elf_entry = elf::load(elf_file_store); elf_entry = elf::load(elf_file_store);
} else {
elf_entry = nullptr;
} }
break; break;

Loading…
Cancel
Save