From a4c33613006b4b70f28b92eedbc87b68412fff6f Mon Sep 17 00:00:00 2001 From: Kizarm Date: Mon, 4 Mar 2024 11:23:10 +0100 Subject: [PATCH] add adc process --- adc/Makefile | 2 +- adc/adcclass.cpp | 38 +++++++++++++++++--------------------- adc/main.cpp | 38 ++++++++++++++++++++++++++++++++++++++ ch32v003/system.h | 4 ++-- 4 files changed, 58 insertions(+), 24 deletions(-) diff --git a/adc/Makefile b/adc/Makefile index 1380a0b..826e24e 100644 --- a/adc/Makefile +++ b/adc/Makefile @@ -17,7 +17,7 @@ DEL = rm -f # zdrojaky OBJS = main.o adcclass.o -#OBJS += usartclass.o print.o +OBJS += usartclass.o print.o include $(TARGET)/$(TOOL).mk BOBJS = $(addprefix $(BLD),$(OBJS)) diff --git a/adc/adcclass.cpp b/adc/adcclass.cpp index 9a024e2..0868fd8 100644 --- a/adc/adcclass.cpp +++ b/adc/adcclass.cpp @@ -1,22 +1,14 @@ #include "system.h" #include "oneway.h" #include "adcclass.h" -#include "gpio.h" - -static GpioClass led (GPIOD, 4); static AdcClass * pInstance = nullptr; -volatile unsigned gCount = 0u; - extern "C" void DMA1_Channel1_IRQHandler( void ) __attribute__((interrupt)); void DMA1_Channel1_IRQHandler( void ) { DMA1_Type::INTFR_DEF state (DMA1.INTFR); DMA1.INTFCR.R = state.R; // clear all if (!pInstance) return; - gCount += 1u; - const bool b = (gCount & 1u) == 0u; - led << b; if (state.B.HTIF1 != RESET) pInstance->send (false); else if (state.B.TCIF1 != RESET) pInstance->send (true); } @@ -47,12 +39,16 @@ static inline void Timer2Init (uint32_t us) noexcept { TIM2.PSC.R = 47u; // 1 MHz Fs TIM2.ATRLR.R = us - 1u; // TRGO update for ADC - TIM2.CTLR2.B.MMS = 2; + TIM2.CTLR2.B.MMS = 2u; } static inline void AdcCalibrate (void) noexcept { - ADC1.RSQR3.B.SQ1 = 1u; // CH1 + // RESET + RCC.APB2PRSTR.B.ADC1RST = SET; + RCC.APB2PRSTR.B.ADC1RST = RESET; + // set channels + ADC1.RSQR3.B.SQ1 = 2u; // CH2 ADC1.RSQR1.B.L = 0u; // 1 regular conversion - ADC1.SAMPTR2_CHARGE2.B.SMP1_TKCG1 = 7u; + ADC1.SAMPTR2_CHARGE2.B.SMP2_TKCG2 = 7u; ADC1.CTLR1.B.SCAN = SET; ADC1.CTLR2.B.ADON = SET; @@ -60,7 +56,6 @@ static inline void AdcCalibrate (void) noexcept { while (ADC1.CTLR2.B.RSTCAL != RESET); // Wait until RSTCAL=0 ADC1.CTLR2.B.CAL = SET; // Launch the calibration by setting CAL while (ADC1.CTLR2.B.CAL != RESET); // Wait until CAL=0 - ADC1.CTLR2.B.ADON = RESET; } typedef __SIZE_TYPE__ size_t; static inline void Dma1Ch1Init (void * ptr) noexcept { @@ -72,12 +67,14 @@ static inline void Dma1Ch1Init (void * ptr) noexcept { DMA1.CNTR1 .R = FULL_LEN; // Configure increment, size, interrupts and circular mode DMA1.CFGR1.modify([] (DMA1_Type::CFGR1_DEF & r) -> auto { - r.B.MINC = SET; - r.B.MSIZE = 1u; - r.B.PSIZE = 1u; - r.B.HTIE = SET; - r.B.TCIE = SET; - r.B.CIRC = SET; + r.B.PL = 3u; // highest priority + r.B.MEM2MEM = RESET; // periferal -> memory + r.B.MINC = SET; // memory increment + r.B.MSIZE = 1u; // 16-bit + r.B.PSIZE = 1u; // 16-bit + r.B.HTIE = SET; // INT Enable HALF + r.B.TCIE = SET; // INT Enable FULL + r.B.CIRC = SET; // Circular MODE // Enable DMA Channel 1 r.B.EN = SET; return r.R; @@ -87,13 +84,12 @@ static inline void AdcPostInit (void) noexcept { ADC1.CTLR2.modify([](ADC1_Type::CTLR2_DEF & r) -> auto { r.B.DMA = SET; r.B.EXTTRIG = SET; - r.B.EXTSEL = 3u; // TRGO event of timer 2 + r.B.EXTSEL = 3u; // TRGO event of timer 2 r.B.SWSTART = SET; - r.B.ADON = SET; return r.R; }); } - +//////////////////////////////////////////////////////////////////////////////////// AdcClass::AdcClass() noexcept : pL (buffer), pH (buffer + HALF_LEN), dst (nullptr) { pInstance = this; EnableClock (); diff --git a/adc/main.cpp b/adc/main.cpp index ffb9622..eb7a517 100644 --- a/adc/main.cpp +++ b/adc/main.cpp @@ -2,11 +2,49 @@ #include "usartclass.h" #include "print.h" #include "adcclass.h" +#include "oneway.h" ////////////////////////////////////// +class Process : public OneWay { + GpioClass led; + UsartClass serial; + Print cout; + FIFO data; + int pass_cnt; + public: + explicit Process () noexcept : OneWay (), + led (GPIOD, 4), serial (115200u), cout (DEC), data(), pass_cnt (0) { + cout += serial; + } + unsigned Send (uint16_t * const ptr, const unsigned len) override { + unsigned sum = 0u; + for (unsigned n=0; n>= 4; + data.Write (static_cast (sum)); + return len; + } + void pass () { + uint16_t avg; + if (!data.Read (avg)) return; + cout << "pass: " << pass_cnt << ", avg = " << static_cast(avg) << EOL; + pass_cnt += 1; + const bool b = pass_cnt & 1; + led << b; + } +}; +////////////////////////////////////// +/* Tohle DEMO je složitější. ADC má + * pevnou frekvenci vzorkování 1kHz, + * vzorky se průměrují v přerušení a + * vypisují (v jiném přerušení) na + * sériový port. + * */ ////////////////////////////////////// static AdcClass adc; +static Process out; int main () { + adc.attach(out); for (;;) { + out.pass(); } return 0; } diff --git a/ch32v003/system.h b/ch32v003/system.h index 2b340ca..566ae24 100644 --- a/ch32v003/system.h +++ b/ch32v003/system.h @@ -32,7 +32,7 @@ struct NVIC_Type { IRER [((uint32_t)(IRQ) >> 5)] = (1 << ((uint32_t)(IRQ) & 0x1F)); } }; -NVIC_Type & NVIC = * reinterpret_cast (0xE000E000); +static NVIC_Type & NVIC = * reinterpret_cast (0xE000E000); struct SysTick_Type { union CTLR_DEF { struct { @@ -68,6 +68,6 @@ struct SysTick_Type { NVIC.EnableIRQ (SysTicK_IRQn); } }; -SysTick_Type & SysTick = * reinterpret_cast (0xE000F000); +static SysTick_Type & SysTick = * reinterpret_cast (0xE000F000); #endif // SYSTEM_H