diff --git a/.gitignore b/.gitignore index 1746b76..ccfe582 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build ChibiOS_* +**/.* diff --git a/source/adc.cpp b/source/adc.cpp new file mode 100644 index 0000000..6ddabb6 --- /dev/null +++ b/source/adc.cpp @@ -0,0 +1,42 @@ +#include "adc.hpp" + +const GPTConfig ADCd::m_gpt_config = { + .frequency = 1000000, + .callback = NULL, + .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ + .dier = 0 +}; + +void ADCd::start() +{ + initPins(); + gptStart(m_gptd, &m_gpt_config); + + m_adc_config.difsel = 0; + m_adc_config.adcdinst = this; + + adcStart(m_adcd, &m_adc_config); + adcSTM32EnableVREF(m_adcd); +} + +adcsample_t *ADCd::getSamples(adcsample_t *buffer, size_t count) +{ + m_is_adc_finished = false; + adcStartConversion(m_adcd, &m_adc_group_config, buffer, count); + gptStartContinuous(m_gptd, 100); // 10kHz + while (!m_is_adc_finished); + return buffer; +} + +void ADCd::initPins() +{ + palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG); +} + +void ADCd::adcEndCallback(ADCDriver *adcd) +{ + auto *_this = reinterpret_cast(adcd->config)->adcdinst; + gptStopTimer(_this->m_gptd); + _this->m_is_adc_finished = true; +} + diff --git a/source/adc.hpp b/source/adc.hpp new file mode 100644 index 0000000..6b1789d --- /dev/null +++ b/source/adc.hpp @@ -0,0 +1,57 @@ +#ifndef STMDSP_ADC_HPP_ +#define STMDSP_ADC_HPP_ + +#include "hal.h" + +class ADCd; + +struct ADCdConfig : public ADCConfig +{ + ADCd *adcdinst; +}; + +class ADCd +{ +public: + constexpr explicit ADCd(ADCDriver& adcd, GPTDriver& gptd) : + m_adcd(&adcd), m_gptd(&gptd), m_adc_config{}, + m_adc_group_config(ADC_GROUP_CONFIG), + m_is_adc_finished(false) {} + + void start(); + adcsample_t *getSamples(adcsample_t *buffer, size_t count); + +private: + static const GPTConfig m_gpt_config; + + ADCDriver *m_adcd; + GPTDriver *m_gptd; + ADCdConfig m_adc_config; + ADCConversionGroup m_adc_group_config; + + bool m_is_adc_finished; + + void initPins(); + static void adcEndCallback(ADCDriver *adcd); + + constexpr static const ADCConversionGroup ADC_GROUP_CONFIG = { + .circular = false, + .num_channels = 1, + .end_cb = ADCd::adcEndCallback, + .error_cb = nullptr, + .cfgr = ADC_CFGR_EXTEN_RISING | + ADC_CFGR_EXTSEL_SRC(12), /* TIM4_TRGO */ + .cfgr2 = 0, + .tr1 = ADC_TR(0, 4095), + .smpr = { + ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_247P5), 0 + }, + .sqr = { + ADC_SQR1_SQ1_N(ADC_CHANNEL_IN5), + 0, 0, 0 + } + }; +}; + +#endif // STMDSP_ADC_HPP_ + diff --git a/source/dac.cpp b/source/dac.cpp new file mode 100644 index 0000000..c7c250d --- /dev/null +++ b/source/dac.cpp @@ -0,0 +1,27 @@ +#include "dac.hpp" + +//static const DACConversionGroup dacGroupConfig = { +// .num_channels = 1, +// .end_cb = NULL, +// .error_cb = NULL, +// .trigger = DAC_TRG(0) +//}; + +void DACd::init() +{ + initPins(); + dacStart(m_driver, &m_config); +} + +void DACd::write(unsigned int channel, uint16_t value) +{ + if (channel < 2) + dacPutChannelX(m_driver, channel, value); +} + +void DACd::initPins() +{ + palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); // DAC out1, out2 + palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); +} + diff --git a/source/dac.hpp b/source/dac.hpp new file mode 100644 index 0000000..687e8cf --- /dev/null +++ b/source/dac.hpp @@ -0,0 +1,24 @@ +#ifndef STMDSP_DAC_HPP_ +#define STMDSP_DAC_HPP_ + +#include "hal.h" + +class DACd +{ +public: + constexpr explicit DACd(DACDriver& driver, const DACConfig& config) : + m_driver(&driver), m_config(config) {} + + void init(); + + void write(unsigned int channel, uint16_t value); + +private: + DACDriver *m_driver; + DACConfig m_config; + + void initPins(); +}; + +#endif // STMDSP_DAC_HPP_ + diff --git a/source/main.cpp b/source/main.cpp index eb77a5d..16ca7a8 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,92 +1,9 @@ #include "ch.h" #include "hal.h" -#include "usbcfg.h" -class dDAC -{ -public: - constexpr dDAC(DACDriver& driver, const DACConfig& config) : - m_driver(&driver), m_config(config) {} - - void init() { - dacStart(m_driver, &m_config); - } - - void writeX(unsigned int channel, uint16_t value) { - if (channel < 2) - dacPutChannelX(m_driver, channel, value); - } - -private: - DACDriver *m_driver; - DACConfig m_config; -}; - -//static const DACConversionGroup dacGroupConfig = { -// .num_channels = 1, -// .end_cb = NULL, -// .error_cb = NULL, -// .trigger = DAC_TRG(0) -//}; - -class dGPT { -public: - constexpr dGPT(GPTDriver& driver, const GPTConfig& config) : - m_driver(&driver), m_config(config) {} - - void init() { - gptStart(m_driver, &m_config); - } - - void startContinuous(unsigned int interval) { - gptStartContinuous(m_driver, interval); - } - - void stop() { - gptStopTimer(m_driver); - } - -private: - GPTDriver *m_driver; - GPTConfig m_config; -}; - -static dGPT gpt (GPTD4, { - .frequency = 1000000, - .callback = NULL, - .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ - .dier = 0 -}); - -static const ADCConfig adcConfig = { - .difsel = 0 -}; - -volatile bool adcFinished = false; -void adcEndCallback(ADCDriver *adcd) -{ - (void)adcd; - gpt.stop(); - adcFinished = true; -} - -static const ADCConversionGroup adcGroupConfig = { - .circular = false, - .num_channels = 1, - .end_cb = adcEndCallback, - .error_cb = NULL, - .cfgr = ADC_CFGR_EXTEN_RISING | - ADC_CFGR_EXTSEL_SRC(12), /* TIM4_TRGO */ - .cfgr2 = 0, - .tr1 = ADC_TR(0, 4095), - .smpr = { - ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_247P5), 0 - }, - .sqr = { - ADC_SQR1_SQ1_N(ADC_CHANNEL_IN5), - 0, 0, 0 - } -}; +#include "adc.hpp" +#include "dac.hpp" +#include "usbserial.hpp" #if CACHE_LINE_SIZE > 0 CC_ALIGN(CACHE_LINE_SIZE) @@ -94,47 +11,29 @@ CC_ALIGN(CACHE_LINE_SIZE) adcsample_t samples[CACHE_SIZE_ALIGN(adcsample_t, 10)]; int main(void) { - halInit(); - chSysInit(); - - palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL); // LED - palSetPadMode(GPIOA, 11, PAL_MODE_ALTERNATE(10)); // USB - palSetPadMode(GPIOA, 12, PAL_MODE_ALTERNATE(10)); - palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG); // Channel A in (1in5) + halInit(); + chSysInit(); - palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); // DAC out1, out2 - palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL); // LED - gpt.init(); + ADCd adc (ADCD1, GPTD4); + adc.start(); - //dDAC dac (DACD1, { + //DACd dac (DACD1, { // .init = 0, // .datamode = DAC_DHRM_12BIT_RIGHT, // .cr = 0 //}); + //dac.start(); + //dac.write(0, 1024); - //dac.init(); - //dac.writeX(0, 1024); - - adcStart(&ADCD1, &adcConfig); - adcSTM32EnableVREF(&ADCD1); - - sduObjectInit(&SDU1); - sduStart(&SDU1, &serusbcfg); - usbDisconnectBus(serusbcfg.usbp); - chThdSleepMilliseconds(1500); - usbStart(serusbcfg.usbp, &usbcfg); - usbConnectBus(serusbcfg.usbp); + USBSeriald usbd (SDU1); + usbd.start(); while (true) { - if (SDU1.config->usbp->state == USB_ACTIVE) { - BaseSequentialStream *bss = (BaseSequentialStream *)&SDU1; - char c = 0; - if (streamRead(bss, (uint8_t *)&c, 1) > 0 && c == 's') { - adcFinished = false; - adcStartConversion(&ADCD1, &adcGroupConfig, samples, 10); - gpt.startContinuous(100); - while (!adcFinished); + if (usbd.active()) { + if (char c; usbd.read(&c) > 0 && c == 's') { + adc.getSamples(samples, 10); for (int i = 0; i < 10; i++) { uint8_t str[5] = { static_cast(samples[i] / 1000 % 10 + '0'), @@ -143,9 +42,9 @@ int main(void) { static_cast(samples[i] % 10 + '0'), ' ' }; - streamWrite(bss, str, 5); + usbd.write(str, 5); } - streamWrite(bss, (uint8_t *)"\r\n", 2); + usbd.write("\r\n", 2); } } chThdSleepMilliseconds(250); diff --git a/source/usbcfg.h b/source/usbcfg.h index 886cd02..2fceccb 100644 --- a/source/usbcfg.h +++ b/source/usbcfg.h @@ -17,6 +17,8 @@ #ifndef USBCFG_H #define USBCFG_H +#include "hal.h" + extern const USBConfig usbcfg; extern SerialUSBConfig serusbcfg; extern SerialUSBDriver SDU1; diff --git a/source/usbserial.cpp b/source/usbserial.cpp new file mode 100644 index 0000000..cead28a --- /dev/null +++ b/source/usbserial.cpp @@ -0,0 +1,41 @@ +#include "usbserial.hpp" + +#include "hal.h" + +void USBSeriald::start() +{ + initPins(); + + sduObjectInit(m_driver); + sduStart(m_driver, &serusbcfg); + + // Reconnect bus so device can re-enumerate on reset + usbDisconnectBus(serusbcfg.usbp); + chThdSleepMilliseconds(1500); + usbStart(serusbcfg.usbp, &usbcfg); + usbConnectBus(serusbcfg.usbp); +} + +bool USBSeriald::active() const +{ + return m_driver->config->usbp->state == USB_ACTIVE; +} + +std::size_t USBSeriald::read(void *buffer, std::size_t count) +{ + auto *bss = reinterpret_cast(m_driver); + return streamRead(bss, static_cast(buffer), count); +} + +std::size_t USBSeriald::write(const void *buffer, std::size_t count) +{ + auto *bss = reinterpret_cast(m_driver); + return streamWrite(bss, static_cast(buffer), count); +} + +void USBSeriald::initPins() +{ + palSetPadMode(GPIOA, 11, PAL_MODE_ALTERNATE(10)); + palSetPadMode(GPIOA, 12, PAL_MODE_ALTERNATE(10)); +} + diff --git a/source/usbserial.hpp b/source/usbserial.hpp new file mode 100644 index 0000000..a65190b --- /dev/null +++ b/source/usbserial.hpp @@ -0,0 +1,28 @@ +#ifndef STMDSP_USBSERIAL_HPP_ +#define STMDSP_USBSERIAL_HPP_ + +#include "usbcfg.h" + +#include + +class USBSeriald +{ +public: + constexpr explicit USBSeriald(SerialUSBDriver& driver) : + m_driver(&driver) {} + + void start(); + + bool active() const; + + std::size_t read(void *buffer, std::size_t count = 1); + std::size_t write(const void *buffer, std::size_t count = 1); + +private: + SerialUSBDriver *m_driver; + + void initPins(); +}; + +#endif // STMDSP_USBSERIAL_HPP_ +