signal gen with dac channel 2

pull/3/head
Clyne 4 years ago
parent f1ad979674
commit 30cd119dba

@ -164,7 +164,7 @@
*/ */
#define STM32_DAC_DUAL_MODE FALSE #define STM32_DAC_DUAL_MODE FALSE
#define STM32_DAC_USE_DAC1_CH1 TRUE #define STM32_DAC_USE_DAC1_CH1 TRUE
#define STM32_DAC_USE_DAC1_CH2 FALSE #define STM32_DAC_USE_DAC1_CH2 TRUE
#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 #define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10
#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 #define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10
#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 #define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2

@ -77,6 +77,29 @@ namespace stmdsp
m_serial.write("S"); m_serial.write("S");
} }
void device::siggen_upload(dacsample_t *buffer, unsigned int size) {
if (connected()) {
uint8_t request[3] = {
'D',
static_cast<uint8_t>(size),
static_cast<uint8_t>(size >> 8)
};
m_serial.write(request, 3);
m_serial.write((uint8_t *)buffer, size * sizeof(dacsample_t));
}
}
void device::siggen_start() {
if (connected())
m_serial.write("W");
}
void device::siggen_stop() {
if (connected())
m_serial.write("w");
}
void device::upload_filter(unsigned char *buffer, size_t size) { void device::upload_filter(unsigned char *buffer, size_t size) {
if (connected()) { if (connected()) {
uint8_t request[3] = { uint8_t request[3] = {

@ -24,6 +24,7 @@ namespace stmdsp
}; };
using adcsample_t = uint16_t; using adcsample_t = uint16_t;
using dacsample_t = uint16_t;
class device class device
{ {
@ -40,12 +41,18 @@ namespace stmdsp
//std::vector<adcsample_t> sample(unsigned long int count = 1); //std::vector<adcsample_t> sample(unsigned long int count = 1);
void continuous_set_buffer_size(unsigned int size);
void continuous_start(); void continuous_start();
void continuous_start_measure(); void continuous_start_measure();
uint32_t continuous_start_get_measurement(); uint32_t continuous_start_get_measurement();
std::vector<adcsample_t> continuous_read(); std::vector<adcsample_t> continuous_read();
void continuous_stop(); void continuous_stop();
void siggen_upload(dacsample_t *buffer, unsigned int size);
void siggen_start();
void siggen_stop();
// buffer is ELF binary
void upload_filter(unsigned char *buffer, size_t size); void upload_filter(unsigned char *buffer, size_t size);
void unload_filter(); void unload_filter();

@ -10,6 +10,9 @@
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/splitter.h> #include <wx/splitter.h>
#include <wx/statusbr.h> #include <wx/statusbr.h>
#include <wx/textdlg.h>
#include <vector>
enum Id { enum Id {
MeasureTimer = 1, MeasureTimer = 1,
@ -25,6 +28,8 @@ enum Id {
MRunMeasure, MRunMeasure,
MRunUpload, MRunUpload,
MRunUnload, MRunUnload,
MRunGenUpload,
MRunGenStart,
MCodeCompile, MCodeCompile,
MCodeDisassemble MCodeDisassemble
}; };
@ -99,6 +104,12 @@ MainFrame::MainFrame() : wxFrame(nullptr, wxID_ANY, "stmdspgui", wxPoint(50, 50)
Bind(wxEVT_MENU, &MainFrame::onRunUnload, this, Id::MRunUnload, wxID_ANY, Bind(wxEVT_MENU, &MainFrame::onRunUnload, this, Id::MRunUnload, wxID_ANY,
menuRun->Append(MRunUnload, "U&nload code")); menuRun->Append(MRunUnload, "U&nload code"));
menuRun->AppendSeparator();
Bind(wxEVT_MENU, &MainFrame::onRunGenUpload, this, Id::MRunGenUpload, wxID_ANY,
menuRun->Append(MRunGenUpload, "&Load signal generator..."));
Bind(wxEVT_MENU, &MainFrame::onRunGenStart, this, Id::MRunGenStart, wxID_ANY,
menuRun->AppendCheckItem(MRunGenStart, "Start &generator"));
Bind(wxEVT_MENU, &MainFrame::onRunCompile, this, Id::MCodeCompile, wxID_ANY, Bind(wxEVT_MENU, &MainFrame::onRunCompile, this, Id::MCodeCompile, wxID_ANY,
menuCode->Append(MCodeCompile, "&Compile code")); menuCode->Append(MCodeCompile, "&Compile code"));
Bind(wxEVT_MENU, &MainFrame::onCodeDisassemble, this, Id::MCodeDisassemble, wxID_ANY, Bind(wxEVT_MENU, &MainFrame::onCodeDisassemble, this, Id::MCodeDisassemble, wxID_ANY,
@ -398,6 +409,59 @@ void MainFrame::onRunStart(wxCommandEvent& ce)
} }
} }
void MainFrame::onRunGenUpload([[maybe_unused]] wxCommandEvent&)
{
if (m_device != nullptr && m_device->connected()) {
wxTextEntryDialog dialog (this, "Enter generator values", "Hey");
if (dialog.ShowModal() == wxID_OK) {
if (wxString values = dialog.GetValue(); !values.IsEmpty()) {
std::vector<stmdsp::dacsample_t> samples;
while (!values.IsEmpty()) {
if (auto number_end = values.find_first_not_of("0123456789");
number_end != wxString::npos && number_end > 0)
{
auto number = values.Left(number_end);
if (unsigned long n; number.ToULong(&n))
samples.push_back(n & 4095);
if (auto next = values.find_first_of("0123456789", number_end + 1);
next != wxString::npos)
{
values = values.Mid(next);
} else {
break;
}
} else {
break;
}
}
m_device->siggen_upload(&samples[0], samples.size());
}
}
} else {
wxMessageBox("No device connected!", "Run", wxICON_WARNING);
m_status_bar->SetStatusText("Please connect.");
}
}
void MainFrame::onRunGenStart(wxCommandEvent& ce)
{
auto menuItem = dynamic_cast<wxMenuItem *>(ce.GetEventUserData());
if (m_device != nullptr && m_device->connected()) {
if (menuItem->IsChecked()) {
m_device->siggen_start();
menuItem->SetItemLabel("Stop &generator");
} else {
m_device->siggen_stop();
menuItem->SetItemLabel("Start &generator");
}
} else {
wxMessageBox("No device connected!", "Run", wxICON_WARNING);
m_status_bar->SetStatusText("Please connect.");
}
}
void MainFrame::onRunUpload([[maybe_unused]] wxCommandEvent&) void MainFrame::onRunUpload([[maybe_unused]] wxCommandEvent&)
{ {
if (auto file = compileEditorCode(); !file.IsEmpty()) { if (auto file = compileEditorCode(); !file.IsEmpty()) {

@ -36,6 +36,8 @@ public:
void onRunStart(wxCommandEvent&); void onRunStart(wxCommandEvent&);
void onRunUpload(wxCommandEvent&); void onRunUpload(wxCommandEvent&);
void onRunUnload(wxCommandEvent&); void onRunUnload(wxCommandEvent&);
void onRunGenUpload(wxCommandEvent&);
void onRunGenStart(wxCommandEvent&);
void onRunCompile(wxCommandEvent&); void onRunCompile(wxCommandEvent&);
void onCodeDisassemble(wxCommandEvent&); void onCodeDisassemble(wxCommandEvent&);

@ -12,6 +12,7 @@
#include "dac.hpp" #include "dac.hpp"
constexpr static const auto dacd = &DACD1; constexpr static const auto dacd = &DACD1;
constexpr static const auto dacd2 = &DACD2;
constexpr static const auto gptd = &GPTD6; constexpr static const auto gptd = &GPTD6;
constexpr static const DACConfig dac_config = { constexpr static const DACConfig dac_config = {
@ -34,27 +35,40 @@ constexpr static const GPTConfig gpt_config = {
.dier = 0 .dier = 0
}; };
static unsigned int dacs_running = 0;
namespace dac namespace dac
{ {
void init() void init()
{ {
palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG);
//palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
dacStart(dacd, &dac_config); dacStart(dacd, &dac_config);
dacStart(dacd2, &dac_config);
gptStart(gptd, &gpt_config); gptStart(gptd, &gpt_config);
} }
void write_start(dacsample_t *buffer, size_t count) void write_start(unsigned int channel, dacsample_t *buffer, size_t count)
{ {
dacStartConversion(dacd, &dac_group_config, buffer, count); if (channel < 2) {
gptStartContinuous(gptd, 25); dacStartConversion(channel == 0 ? dacd : dacd2, &dac_group_config, buffer, count);
if (dacs_running == 0)
gptStartContinuous(gptd, 25);
dacs_running |= 1 << channel;
}
} }
void write_stop() void write_stop(unsigned int channel)
{ {
gptStopTimer(gptd); if (channel < 2) {
dacStopConversion(dacd); dacStopConversion(channel == 0 ? dacd : dacd2);
dacs_running &= ~(1 << channel);
if (dacs_running == 0)
gptStopTimer(gptd);
}
} }
} }

@ -17,8 +17,8 @@
namespace dac namespace dac
{ {
void init(); void init();
void write_start(dacsample_t *buffer, size_t count); void write_start(unsigned int channel, dacsample_t *buffer, size_t count);
void write_stop(); void write_stop(unsigned int channel);
} }
#endif // STMDSP_DAC_HPP_ #endif // STMDSP_DAC_HPP_

@ -77,6 +77,10 @@ static std::array<adcsample_t, CACHE_SIZE_ALIGN(adcsample_t, MAX_SAMPLE_BUFFER_S
CC_ALIGN(CACHE_LINE_SIZE) 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;
#if CACHE_LINE_SIZE > 0
CC_ALIGN(CACHE_LINE_SIZE)
#endif
static std::array<dacsample_t, CACHE_SIZE_ALIGN(dacsample_t, MAX_SAMPLE_BUFFER_SIZE)> dac2_samples;
static uint8_t elf_file_store[MAX_ELF_FILE_SIZE]; static uint8_t elf_file_store[MAX_ELF_FILE_SIZE];
static elf::entry_t elf_entry = nullptr; static elf::entry_t elf_entry = nullptr;
@ -112,6 +116,7 @@ int main()
} }
static unsigned int dac_sample_count = MAX_SAMPLE_BUFFER_SIZE; static unsigned int dac_sample_count = MAX_SAMPLE_BUFFER_SIZE;
static unsigned int dac2_sample_count = MAX_SAMPLE_BUFFER_SIZE;
static unsigned int adc_sample_count = MAX_SAMPLE_BUFFER_SIZE; static unsigned int adc_sample_count = MAX_SAMPLE_BUFFER_SIZE;
static bool adc_preloaded = false; static bool adc_preloaded = false;
static bool dac_preloaded = false; static bool dac_preloaded = false;
@ -133,6 +138,8 @@ void main_loop()
usbserial::read(&adc_samples[0], adc_sample_count * sizeof(adcsample_t)); usbserial::read(&adc_samples[0], adc_sample_count * sizeof(adcsample_t));
break; break;
case 'b':
break;
case 'B': case 'B':
if (run_status == RunStatus::Idle) { if (run_status == RunStatus::Idle) {
if (usbserial::read(&cmd[1], 2) == 2) { if (usbserial::read(&cmd[1], 2) == 2) {
@ -155,7 +162,17 @@ void main_loop()
usbserial::write(dac_samples.data(), dac_sample_count * sizeof(dacsample_t)); usbserial::write(dac_samples.data(), dac_sample_count * sizeof(dacsample_t));
break; break;
case 'D': case 'D':
usbserial::read(&dac_samples[0], dac_sample_count * sizeof(dacsample_t)); if (usbserial::read(&cmd[1], 2) == 2) {
unsigned int count = cmd[1] | (cmd[2] << 8);
if (count <= MAX_SAMPLE_BUFFER_SIZE / 2) {
dac2_sample_count = count;
usbserial::read(&dac2_samples[0], dac2_sample_count * sizeof(dacsample_t));
} else {
error_queue_add(Error::BadParam);
}
} else {
error_queue_add(Error::BadParamSize);
}
break; break;
// 'E' - Reads in and loads the compiled conversion code binary from USB. // 'E' - Reads in and loads the compiled conversion code binary from USB.
@ -211,7 +228,7 @@ void main_loop()
if (!adc_preloaded) if (!adc_preloaded)
adc::read_start(signal_operate_measure, &adc_samples[0], adc_sample_count); adc::read_start(signal_operate_measure, &adc_samples[0], adc_sample_count);
if (!dac_preloaded) if (!dac_preloaded)
dac::write_start(&dac_samples[0], dac_sample_count); dac::write_start(0, &dac_samples[0], dac_sample_count);
} else { } else {
error_queue_add(Error::NotIdle); error_queue_add(Error::NotIdle);
} }
@ -232,7 +249,7 @@ void main_loop()
if (!adc_preloaded) if (!adc_preloaded)
adc::read_start(signal_operate, &adc_samples[0], adc_sample_count); adc::read_start(signal_operate, &adc_samples[0], adc_sample_count);
if (!dac_preloaded) if (!dac_preloaded)
dac::write_start(&dac_samples[0], dac_sample_count); dac::write_start(0, &dac_samples[0], dac_sample_count);
} else { } else {
error_queue_add(Error::NotIdle); error_queue_add(Error::NotIdle);
} }
@ -251,13 +268,20 @@ void main_loop()
case 'S': case 'S':
if (run_status == RunStatus::Running) { if (run_status == RunStatus::Running) {
if (!dac_preloaded) if (!dac_preloaded)
dac::write_stop(); dac::write_stop(0);
if (!adc_preloaded) if (!adc_preloaded)
adc::read_stop(); adc::read_stop();
run_status = RunStatus::Idle; run_status = RunStatus::Idle;
} }
break; break;
case 'W':
dac::write_start(1, &dac2_samples[0], dac2_sample_count);
break;
case 'w':
dac::write_stop(1);
break;
default: default:
break; break;
} }
@ -272,7 +296,7 @@ void conversion_abort()
{ {
elf_entry = nullptr; elf_entry = nullptr;
if (!dac_preloaded) if (!dac_preloaded)
dac::write_stop(); dac::write_stop(0);
if (!adc_preloaded) if (!adc_preloaded)
adc::read_stop(); adc::read_stop();
error_queue_add(Error::ConversionAborted); error_queue_add(Error::ConversionAborted);

Loading…
Cancel
Save