aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2020-08-20 17:06:47 -0400
committerClyne Sullivan <clyne@bitgloo.com>2020-08-20 17:06:47 -0400
commit989f4038c6d2a3e5bbee04fa25df181810af621e (patch)
tree73987829cac7e15ab8763211bcef582ec885f3a2
parent2ceb20f4d48a8f163528f86fda484e977438bc80 (diff)
parent29e4b4cf091dd47c9f435ef1d315a1609b83fb19 (diff)
merge elf loading and adc streaming
-rw-r--r--.gitignore1
-rw-r--r--filter/Makefile14
-rw-r--r--filter/test.cpp15
-rw-r--r--source/adc.cpp145
-rw-r--r--source/adc.hpp37
-rw-r--r--source/dac.cpp39
-rw-r--r--source/dac.hpp9
-rw-r--r--source/elf_format.hpp93
-rw-r--r--source/elf_load.cpp77
-rw-r--r--source/elf_load.hpp12
-rw-r--r--source/main.cpp30
-rw-r--r--source/usbserial.cpp61
-rw-r--r--source/usbserial.hpp12
13 files changed, 388 insertions, 157 deletions
diff --git a/.gitignore b/.gitignore
index c24aa5f..d01aefe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,5 +3,6 @@ ChibiOS_*
**/.*
gui/stmdspgui
**/*.o
+**/*.so
perf*
diff --git a/filter/Makefile b/filter/Makefile
new file mode 100644
index 0000000..a1ce186
--- /dev/null
+++ b/filter/Makefile
@@ -0,0 +1,14 @@
+all:
+ @arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -Os --specs=nosys.specs -nostartfiles -fPIE -c test.cpp
+ @arm-none-eabi-ld -shared -n -N -z max-page-size=512 -Ttext-segment=0 \
+ test.o -o test.so
+ @arm-none-eabi-strip -s -S --strip-unneeded test.so
+ @arm-none-eabi-objcopy --remove-section .dynsym \
+ --remove-section .dynstr \
+ --remove-section .dynamic \
+ --remove-section .hash \
+ --remove-section .ARM.exidx \
+ --remove-section .ARM.attributes \
+ --remove-section .comment \
+ test.so
+
diff --git a/filter/test.cpp b/filter/test.cpp
new file mode 100644
index 0000000..0953539
--- /dev/null
+++ b/filter/test.cpp
@@ -0,0 +1,15 @@
+#include <cstdint>
+
+using adcsample_t = uint16_t;
+__attribute__((section(".process_data")))
+void process_data(adcsample_t *samples, unsigned int size);
+
+////////////////////////////////////////////////////////////////////////////////
+
+void process_data(adcsample_t *samples, unsigned int size)
+{
+ size--;
+ for (unsigned int i = 0; i < size; i++)
+ samples[i] = samples[i] * 80 / 100 + samples[i + 1] * 20 / 100;
+}
+
diff --git a/source/adc.cpp b/source/adc.cpp
index e754e0e..f2903c3 100644
--- a/source/adc.cpp
+++ b/source/adc.cpp
@@ -18,7 +18,7 @@ constexpr static const ADCConfig adc_config = {
.difsel = 0
};
-void adc_read_callback(ADCDriver *);
+static void adc_read_callback(ADCDriver *);
/*constexpr*/ static ADCConversionGroup adc_group_config = {
.circular = false,
@@ -45,51 +45,88 @@ constexpr static const GPTConfig gpt_config = {
};
static bool adc_is_read_finished = false;
-static bool adc_is_read_continuous = false;
static adcsample_t *adc_current_buffer = nullptr;
static size_t adc_current_buffer_size = 0;
-static adc_operation_t adc_operation_func = nullptr;
+static adc::operation_t adc_operation_func = nullptr;
-void adc_init()
+namespace adc
{
- palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG);
-
- gptStart(gptd, &gpt_config);
- adcStart(adcd, &adc_config);
- adcSTM32EnableVREF(adcd);
-}
-
-adcsample_t *adc_read(adcsample_t *buffer, size_t count)
-{
- adc_is_read_finished = false;
- adc_is_read_continuous = false;
- adc_group_config.circular = false;
- adcStartConversion(adcd, &adc_group_config, buffer, count);
- gptStartContinuous(gptd, 100); // 10kHz
- while (!adc_is_read_finished);
- return buffer;
-}
-
-void adc_read_start(adc_operation_t operation_func, adcsample_t *buffer, size_t count)
-{
- adc_is_read_continuous = true;
- adc_current_buffer = buffer;
- adc_current_buffer_size = count;
- adc_operation_func = operation_func;
- adc_group_config.circular = true;
- adcStartConversion(adcd, &adc_group_config, buffer, count);
- gptStartContinuous(gptd, 100); // 10kHz
-}
+ void init()
+ {
+ palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG);
+
+ gptStart(gptd, &gpt_config);
+ adcStart(adcd, &adc_config);
+ adcSTM32EnableVREF(adcd);
+ }
+
+ adcsample_t *read(adcsample_t *buffer, size_t count)
+ {
+ adc_is_read_finished = false;
+ adc_group_config.circular = false;
+ adcStartConversion(adcd, &adc_group_config, buffer, count);
+ gptStartContinuous(gptd, 100); // 10kHz
+ while (!adc_is_read_finished);
+ return buffer;
+ }
-void adc_read_stop()
-{
- adc_is_read_continuous = false;
- gptStopTimer(gptd);
+ void read_start(operation_t operation_func, adcsample_t *buffer, size_t count)
+ {
+ adc_current_buffer = buffer;
+ adc_current_buffer_size = count;
+ adc_operation_func = operation_func;
+ adc_group_config.circular = true;
+ adcStartConversion(adcd, &adc_group_config, buffer, count);
+ gptStartContinuous(gptd, 100); // 10kHz
+ }
+
+ void read_stop()
+ {
+ gptStopTimer(gptd);
+ adc_group_config.circular = false;
+ adc_current_buffer = nullptr;
+ adc_current_buffer_size = 0;
+ adc_operation_func = nullptr;
+ }
+
+ void set_rate(rate r)
+ {
+ uint32_t val = 0;
+
+ switch (r) {
+ case rate::R2P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_2P5);
+ break;
+ case rate::R6P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_6P5);
+ break;
+ case rate::R12P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_12P5);
+ break;
+ case rate::R24P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_24P5);
+ break;
+ case rate::R47P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_47P5);
+ break;
+ case rate::R92P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_92P5);
+ break;
+ case rate::R247P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_247P5);
+ break;
+ case rate::R640P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_640P5);
+ break;
+ }
+
+ adc_group_config.smpr[0] = val;
+ }
}
void adc_read_callback(ADCDriver *driver)
{
- if (!adc_is_read_continuous) {
+ if (!adc_group_config.circular) {
gptStopTimer(gptd);
adc_is_read_finished = true;
} else if (adc_operation_func != nullptr) {
@@ -104,37 +141,3 @@ void adc_read_callback(ADCDriver *driver)
}
}
-void adc_set_rate(ADCRate rate)
-{
- uint32_t val = 0;
-
- switch (rate) {
- case ADCRate::R2P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_2P5);
- break;
- case ADCRate::R6P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_6P5);
- break;
- case ADCRate::R12P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_12P5);
- break;
- case ADCRate::R24P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_24P5);
- break;
- case ADCRate::R47P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_47P5);
- break;
- case ADCRate::R92P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_92P5);
- break;
- case ADCRate::R247P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_247P5);
- break;
- case ADCRate::R640P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_640P5);
- break;
- }
-
- adc_group_config.smpr[0] = val;
-}
-
diff --git a/source/adc.hpp b/source/adc.hpp
index 15e343a..376b156 100644
--- a/source/adc.hpp
+++ b/source/adc.hpp
@@ -14,24 +14,27 @@
#include "hal.h"
-enum class ADCRate {
- R2P5,
- R6P5,
- R12P5,
- R24P5,
- R47P5,
- R92P5,
- R247P5,
- R640P5
-};
+namespace adc
+{
+ using operation_t = void (*)(adcsample_t *buffer, size_t count);
-using adc_operation_t = void (*)(adcsample_t *buffer, size_t count);
-
-void adc_init();
-adcsample_t *adc_read(adcsample_t *buffer, size_t count);
-void adc_read_start(adc_operation_t operation_func, adcsample_t *buffer, size_t count);
-void adc_read_stop();
-void adc_set_rate(ADCRate rate);
+ enum class rate {
+ R2P5,
+ R6P5,
+ R12P5,
+ R24P5,
+ R47P5,
+ R92P5,
+ R247P5,
+ R640P5
+ };
+
+ void init();
+ adcsample_t *read(adcsample_t *buffer, size_t count);
+ void read_start(operation_t operation_func, adcsample_t *buffer, size_t count);
+ void read_stop();
+ void set_rate(rate r);
+}
#endif // STMDSP_ADC_HPP_
diff --git a/source/dac.cpp b/source/dac.cpp
index d2bcf37..6096d8e 100644
--- a/source/dac.cpp
+++ b/source/dac.cpp
@@ -34,24 +34,27 @@ constexpr static const GPTConfig gpt_config = {
.dier = 0
};
-void dac_init()
+namespace dac
{
- palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG);
- //palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
-
- dacStart(dacd, &dac_config);
- gptStart(gptd, &gpt_config);
-}
-
-void dac_write_start(dacsample_t *buffer, size_t count)
-{
- dacStartConversion(dacd, &dac_group_config, buffer, count);
- gptStartContinuous(gptd, 1);
-}
-
-void dac_write_stop()
-{
- gptStopTimer(gptd);
- dacStopConversion(dacd);
+ void init()
+ {
+ palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG);
+ //palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
+
+ dacStart(dacd, &dac_config);
+ gptStart(gptd, &gpt_config);
+ }
+
+ void write_start(dacsample_t *buffer, size_t count)
+ {
+ dacStartConversion(dacd, &dac_group_config, buffer, count);
+ gptStartContinuous(gptd, 1);
+ }
+
+ void write_stop()
+ {
+ gptStopTimer(gptd);
+ dacStopConversion(dacd);
+ }
}
diff --git a/source/dac.hpp b/source/dac.hpp
index ce67f40..9d529bf 100644
--- a/source/dac.hpp
+++ b/source/dac.hpp
@@ -14,9 +14,12 @@
#include "hal.h"
-void dac_init();
-void dac_write_start(dacsample_t *buffer, size_t count);
-void dac_write_stop();
+namespace dac
+{
+ void init();
+ void write_start(dacsample_t *buffer, size_t count);
+ void write_stop();
+}
#endif // STMDSP_DAC_HPP_
diff --git a/source/elf_format.hpp b/source/elf_format.hpp
new file mode 100644
index 0000000..ed74c7b
--- /dev/null
+++ b/source/elf_format.hpp
@@ -0,0 +1,93 @@
+#ifndef STMDSP_ELF_FORMAT_HPP_
+#define STMDSP_ELF_FORMAT_HPP_
+
+#include <cstdint>
+
+#define EI_NIDENT 16
+
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_RESERVED 0x70000000
+
+#define ELF32_ST_BIND(i) ((i) >> 4)
+#define ELF32_ST_TYPE(i) ((i) & 0xF)
+#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0xF))
+
+#define ELF32_R_SYM(i) ((i) >> 8)
+#define ELF32_R_TYPE(i) ((i) & 0xFF)
+#define ELF32_R_INFO(s, t) (((s) << 8) + ((t) & 0xFF))
+
+typedef uint32_t Elf32_Addr;
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off;
+typedef uint32_t Elf32_Sword;
+typedef uint32_t Elf32_Word;
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry;
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} __attribute__((packed)) Elf32_Ehdr;
+
+typedef struct {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} __attribute__((packed)) Elf32_Shdr;
+
+typedef struct {
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf32_Half st_shndx;
+} __attribute__((packed)) Elf32_Sym;
+
+typedef struct {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+} __attribute__((packed)) Elf32_Rel;
+
+typedef struct {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+ Elf32_Sword r_addend;
+} __attribute__((packed)) Elf32_Rela;
+
+typedef struct {
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} __attribute__((packed)) Elf32_Phdr;
+
+#endif // STMDSP_ELF_FORMAT_HPP_
+
diff --git a/source/elf_load.cpp b/source/elf_load.cpp
new file mode 100644
index 0000000..661dbc3
--- /dev/null
+++ b/source/elf_load.cpp
@@ -0,0 +1,77 @@
+#include "elf_load.hpp"
+#include "elf_format.hpp"
+
+#include <algorithm>
+#include <cstring>
+
+extern void *elf_load_offset;
+static const unsigned char elf_header[] = { '\177', 'E', 'L', 'F' };
+
+template<typename T>
+constexpr static auto ptr_from_offset(void *base, uint32_t offset)
+{
+ return reinterpret_cast<T>(reinterpret_cast<uint8_t *>(base) + offset);
+}
+
+static Elf32_Shdr *find_section(Elf32_Ehdr *ehdr, const char *name);
+
+namespace elf {
+
+entry_t elf_load(void *elf_data)
+{
+ auto ehdr = reinterpret_cast<Elf32_Ehdr *>(elf_data);
+ if (std::equal(ehdr->e_ident, ehdr->e_ident + 4, elf_header))
+ return nullptr;
+
+ auto phdr = ptr_from_offset<Elf32_Phdr *>(elf_data, ehdr->e_phoff);
+ for (Elf32_Half i = 0; i < ehdr->e_phnum; i++) {
+ if (phdr->p_type == PT_LOAD) {
+ std::memcpy(ptr_from_offset<void *>(elf_load_offset, phdr->p_vaddr),
+ ptr_from_offset<void *>(elf_data, phdr->p_offset),
+ phdr->p_filesz);
+ //break;
+ }
+ }
+
+ // Zero .bss section
+ if (auto bss_section = find_section(ehdr, ".bss"); bss_section) {
+ auto bss = ptr_from_offset<uint32_t *>(elf_load_offset, bss_section->sh_addr);
+ std::fill(bss, bss + bss_section->sh_size / sizeof(uint32_t), 0);
+ }
+
+ // Fix global offset table (GOT) entries
+ if (auto got_section = find_section(ehdr, ".got"); got_section) {
+ auto got = ptr_from_offset<void **>(elf_load_offset, got_section->sh_addr);
+ for (size_t i = 0; i < got_section->sh_size / sizeof(void *); i++)
+ got[i] = ptr_from_offset<void *>(got[i], reinterpret_cast<uint32_t>(elf_load_offset));
+ }
+
+ //// Run any initial constructors
+ //if (auto init_section = find_section(ehdr, ".init_array"); init_section) {
+ // auto init_array = reinterpret_cast<void (**)()>(elf_load_offset + init_section->sh_addr);
+ // std::for_each(init_array, init_array + init_section->sh_size / sizeof(void (*)()),
+ // [elf_load_offset](auto func) { (func + elf_load_offset)(); });
+ //}
+
+ return ptr_from_offset<entry_t>(elf_load_offset, ehdr->e_entry);
+}
+
+} // namespace elf
+
+Elf32_Shdr *find_section(Elf32_Ehdr *ehdr, const char *name)
+{
+ auto shdr = ptr_from_offset<Elf32_Shdr *>(ehdr, ehdr->e_shoff);
+ auto shdr_str = ptr_from_offset<Elf32_Shdr *>(ehdr,
+ ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
+
+ for (Elf32_Half i = 0; i < ehdr->e_shnum; i++) {
+ char *section = ptr_from_offset<char *>(ehdr, shdr_str->sh_offset) + shdr->sh_name;
+ if (!strcmp(section, name))
+ return shdr;
+
+ shdr = ptr_from_offset<Elf32_Shdr *>(shdr, ehdr->e_shentsize);
+ }
+
+ return 0;
+}
+
diff --git a/source/elf_load.hpp b/source/elf_load.hpp
new file mode 100644
index 0000000..722b19b
--- /dev/null
+++ b/source/elf_load.hpp
@@ -0,0 +1,12 @@
+#ifndef ELF_LOAD_HPP_
+#define ELF_LOAD_HPP_
+
+namespace elf
+{
+ using entry_t = void (*)();
+
+ entry_t load(void *file_data);
+}
+
+#endif // ELF_LOAD_HPP_
+
diff --git a/source/main.cpp b/source/main.cpp
index 07c73ba..f1170a6 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -35,45 +35,45 @@ int main()
palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL); // LED
- adc_init();
- dac_init();
- usbserial_init();
+ adc::init();
+ dac::init();
+ usbserial::init();
static unsigned int dac_sample_count = 2048;
while (true) {
- if (usbserial_is_active()) {
+ if (usbserial::is_active()) {
// Expect to receive a byte command 'packet'.
- if (char cmd[3]; usbserial_read(&cmd, 1) > 0) {
+ if (char cmd[3]; usbserial::read(&cmd, 1) > 0) {
switch (cmd[0]) {
case 'r': // Read in analog signal
- if (usbserial_read(&cmd[1], 2) < 2)
+ if (usbserial::read(&cmd[1], 2) < 2)
break;
if (auto count = std::min(static_cast<unsigned int>(cmd[1] | (cmd[2] << 8)), adc_samples.size()); count > 0) {
- adc_read(&adc_samples[0], count);
- usbserial_write(adc_samples.data(), count * sizeof(adcsample_t));
+ adc::read(&adc_samples[0], count);
+ usbserial::write(adc_samples.data(), count * sizeof(adcsample_t));
}
break;
case 'R':
- adc_read_start(signal_operate, &adc_samples[0], adc_samples.size() * sizeof(adcsample_t));
+ adc::read_start(signal_operate, &adc_samples[0], adc_samples.size() * sizeof(adcsample_t));
break;
case 'S':
- adc_read_stop();
+ adc::read_stop();
break;
case 'W':
- if (usbserial_read(&cmd[1], 2) < 2)
+ if (usbserial::read(&cmd[1], 2) < 2)
break;
if (auto count = std::min(static_cast<unsigned int>(cmd[1] | (cmd[2] << 8)), dac_samples.size()); count > 0)
dac_sample_count = count;
else
- dac_write_stop();
+ dac::write_stop();
break;
case 'w':
- if (usbserial_read(&dac_samples[0], 2 * dac_sample_count) != 2 * dac_sample_count)
+ if (usbserial::read(&dac_samples[0], 2 * dac_sample_count) != 2 * dac_sample_count)
break;
- dac_write_start(&dac_samples[0], dac_sample_count);
+ dac::write_start(&dac_samples[0], dac_sample_count);
break;
case 'i': // Identify ourself as an stmdsp device
- usbserial_write("stmdsp", 6);
+ usbserial::write("stmdsp", 6);
break;
default:
break;
diff --git a/source/usbserial.cpp b/source/usbserial.cpp
index 5d605e6..ec2fc5d 100644
--- a/source/usbserial.cpp
+++ b/source/usbserial.cpp
@@ -15,35 +15,38 @@
constexpr static const auto sdud = &SDU1;
-void usbserial_init()
+namespace usbserial
{
- palSetPadMode(GPIOA, 11, PAL_MODE_ALTERNATE(10));
- palSetPadMode(GPIOA, 12, PAL_MODE_ALTERNATE(10));
-
- sduObjectInit(sdud);
- sduStart(sdud, &serusbcfg);
-
- // Reconnect bus so device can re-enumerate on reset
- usbDisconnectBus(serusbcfg.usbp);
- chThdSleepMilliseconds(1500);
- usbStart(serusbcfg.usbp, &usbcfg);
- usbConnectBus(serusbcfg.usbp);
-}
-
-bool usbserial_is_active()
-{
- return sdud->config->usbp->state == USB_ACTIVE;
-}
-
-size_t usbserial_read(void *buffer, size_t count)
-{
- auto bss = reinterpret_cast<BaseSequentialStream *>(sdud);
- return streamRead(bss, static_cast<uint8_t *>(buffer), count);
-}
-
-size_t usbserial_write(const void *buffer, size_t count)
-{
- auto bss = reinterpret_cast<BaseSequentialStream *>(sdud);
- return streamWrite(bss, static_cast<const uint8_t *>(buffer), count);
+ void init()
+ {
+ palSetPadMode(GPIOA, 11, PAL_MODE_ALTERNATE(10));
+ palSetPadMode(GPIOA, 12, PAL_MODE_ALTERNATE(10));
+
+ sduObjectInit(sdud);
+ sduStart(sdud, &serusbcfg);
+
+ // Reconnect bus so device can re-enumerate on reset
+ usbDisconnectBus(serusbcfg.usbp);
+ chThdSleepMilliseconds(1500);
+ usbStart(serusbcfg.usbp, &usbcfg);
+ usbConnectBus(serusbcfg.usbp);
+ }
+
+ bool is_active()
+ {
+ return sdud->config->usbp->state == USB_ACTIVE;
+ }
+
+ size_t read(void *buffer, size_t count)
+ {
+ auto bss = reinterpret_cast<BaseSequentialStream *>(sdud);
+ return streamRead(bss, static_cast<uint8_t *>(buffer), count);
+ }
+
+ size_t write(const void *buffer, size_t count)
+ {
+ auto bss = reinterpret_cast<BaseSequentialStream *>(sdud);
+ return streamWrite(bss, static_cast<const uint8_t *>(buffer), count);
+ }
}
diff --git a/source/usbserial.hpp b/source/usbserial.hpp
index 4b0eab2..4c33d51 100644
--- a/source/usbserial.hpp
+++ b/source/usbserial.hpp
@@ -14,10 +14,14 @@
#include "hal.h"
-void usbserial_init();
-bool usbserial_is_active();
-size_t usbserial_read(void *buffer, size_t count);
-size_t usbserial_write(const void *buffer, size_t count);
+namespace usbserial
+{
+ void init();
+ bool is_active();
+
+ size_t read(void *buffer, size_t count);
+ size_t write(const void *buffer, size_t count);
+}
#endif // STMDSP_USBSERIAL_HPP_