From b1d64e1ab3713f92ba5572485e1afa2b9e5d85d4 Mon Sep 17 00:00:00 2001 From: Kizarm Date: Sun, 12 May 2024 16:53:28 +0200 Subject: [PATCH] gsm -> voltmetr --- V203/gsm/Makefile | 2 +- V203/gsm/adcdma.cpp | 114 ++++++++++++++++++++++++++++++++++++++++++++ V203/gsm/adcdma.h | 21 ++++++++ V203/gsm/gsmdata.c | 35 +++++++++++++- V203/gsm/main.cpp | 63 ++++++++++++++++++++++-- 5 files changed, 227 insertions(+), 8 deletions(-) create mode 100644 V203/gsm/adcdma.cpp create mode 100644 V203/gsm/adcdma.h diff --git a/V203/gsm/Makefile b/V203/gsm/Makefile index d3538d6..0f8307b 100644 --- a/V203/gsm/Makefile +++ b/V203/gsm/Makefile @@ -18,7 +18,7 @@ DEL = rm -f # zdrojaky OBJS = main.o pwmclass.o -OBJS += player.o GsmDecoder.o gsmdata.o wrap.o +OBJS += player.o GsmDecoder.o gsmdata.o wrap.o adcdma.o include $(TARGET)/$(TOOL).mk BOBJS = $(addprefix $(BLD),$(OBJS)) diff --git a/V203/gsm/adcdma.cpp b/V203/gsm/adcdma.cpp new file mode 100644 index 0000000..d9b8c3b --- /dev/null +++ b/V203/gsm/adcdma.cpp @@ -0,0 +1,114 @@ +#include "system.h" +#include "oneway.h" +#include "adcdma.h" + +static AdcDma * pInstance = nullptr; + +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; + if (state.B.HTIF1 != RESET) pInstance->send (false); + else if (state.B.TCIF1 != RESET) pInstance->send (true); +} + +static inline void EnableClock (void) noexcept { + // Enable DMA + RCC.AHBPCENR.modify([](RCC_Type::AHBPCENR_DEF & r) -> auto { + r.B.SRAMEN = SET; + r.B.DMA1EN = SET; + return r.R; + }); + // Enable ADC + GPIOA + RCC.APB2PCENR.modify([](RCC_Type::APB2PCENR_DEF & r) -> auto { + r.B.ADC1EN = SET; + r.B.IOPAEN = SET; + return r.R; + }); + RCC.APB1PCENR.B.TIM3EN = SET; // Enable TIM3 + RCC.CFGR0.B.ADCPRE = 3u; // 11: PCLK2 divided by 8 // max 14 MHz (18) ? + // PIN PA2 / A2 + GPIOA.CFGLR.modify([](GPIOA_Type::CFGLR_DEF & r) -> auto { + r.B.MODE2 = 0u; + r.B.CNF2 = 0u; + return r.R; + }); +} +static inline void TimerInit (uint32_t us) noexcept { + TIM3.PSC.R = 143u; // 1 MHz Fs + TIM3.ATRLR.R = us - 1u; + // TRGO update for ADC + TIM3.CTLR2.B.MMS = 2u; +} +static inline void AdcCalibrate (void) noexcept { + // RESET + RCC.APB2PRSTR.B.ADC1RST = SET; + RCC.APB2PRSTR.B.ADC1RST = RESET; + // set channels + + ADC1.RSQR3__CHANNEL.B.SQ1__CHSEL = 2u; // CH2 + ADC1.SAMPTR2_CHARGE2.B.SMP2_TKCG2 = 7u; + /* + ADC1.RSQR3__CHANNEL.B.SQ1__CHSEL = 16u; // teplota + ADC1.SAMPTR1_CHARGE1.B.SMP16_TKCG16 = 7u; + */ + ADC1.RSQR1.B.L = 0u; // 1 regular conversion + ADC1.CTLR1.B.SCAN = SET; + + ADC1.CTLR2.B.ADON = SET; +//ADC1.CTLR2.B.TSVREFE = SET; + ADC1.CTLR2.B.RSTCAL = SET; // Launch the calibration by setting RSTCAL + 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 +} +typedef __SIZE_TYPE__ size_t; +static inline void Dma1Ch1Init (void * ptr) noexcept { + // Configure the peripheral data register address + DMA1.PADDR1.R = reinterpret_cast (& ADC1.RDATAR_DR_ACT_DCG); + // Configure the memory address + DMA1.MADDR1.R = reinterpret_cast (ptr); + // Configure the number of DMA tranfer to be performs on DMA channel 1 + DMA1.CNTR1 .R = AFULL_LEN; + // Configure increment, size, interrupts and circular mode + DMA1.CFGR1.modify([] (DMA1_Type::CFGR1_DEF & r) -> auto { + 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; + }); +} +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 = 4u; // TRGO event of timer 3 + r.B.SWSTART = SET; + return r.R; + }); +} +//////////////////////////////////////////////////////////////////////////////////// +AdcDma::AdcDma() noexcept : pL (buffer), pH (buffer + AHALF_LEN), dst (nullptr) { + pInstance = this; + EnableClock (); + TimerInit (1000u); + NVIC.EnableIRQ (DMA1_Channel1_IRQn); + AdcCalibrate(); + Dma1Ch1Init (buffer); + AdcPostInit (); + // start timer + TIM3.CTLR1.B.CEN = SET; +} +inline void AdcDma::send(const bool b) { + if (!dst) return; + if (b) dst->Send (pH, AHALF_LEN); + else dst->Send (pL, AHALF_LEN); +} diff --git a/V203/gsm/adcdma.h b/V203/gsm/adcdma.h new file mode 100644 index 0000000..05a4fc6 --- /dev/null +++ b/V203/gsm/adcdma.h @@ -0,0 +1,21 @@ +#ifndef ADCDMA_H +#define ADCDMA_H +#include + +class OneWay; +static constexpr unsigned AHALF_LEN = 120u; +static constexpr unsigned AFULL_LEN = AHALF_LEN * 2u; + +class AdcDma { + uint16_t * pL; + uint16_t * pH; + uint16_t buffer [AFULL_LEN]; + OneWay * dst; + public: + explicit AdcDma () noexcept; + void attach (OneWay & d) { dst = & d; } + void send (const bool b); + +}; + +#endif // ADCDMA_H diff --git a/V203/gsm/gsmdata.c b/V203/gsm/gsmdata.c index 8094c47..f95c6ce 100644 --- a/V203/gsm/gsmdata.c +++ b/V203/gsm/gsmdata.c @@ -1259,7 +1259,8 @@ static const gsm_frame gsm_data_hafo[] = { {0xd0,0x9b,0x9a,0xe1,0x5a,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x54,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,}, {0xd0,0x60,0xa2,0xe1,0x5a,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x8e,0x49,0x24,}, }; -static const gsm_frame gsm_data_units[] = { +/* +static const gsm_frame gsm_data_units[] = { // stupňů celsia {0xdb,0xe4,0xd2,0x14,0xd2,0x50,0x02,0x36,0xdb,0x69,0xa0,0xa2,0x52,0xc1,0x97,0x52,0x50,0x2a,0xa6,0x7a,0xa2,0x34,0x78,0x78,0x58,0x6c,0x6f,0x01,0xd9,0x28,0xbc,0xeb,0xdf,}, {0xda,0xa4,0xe3,0xaa,0x23,0x63,0x02,0x6c,0x6b,0xe7,0x09,0x53,0x97,0xa7,0x49,0x1b,0xa8,0xd5,0x18,0x53,0x29,0xce,0xa3,0x96,0x67,0x68,0x53,0x28,0xcd,0xcc,0x72,0x63,0x61,}, {0xd8,0xec,0xe4,0x71,0xe2,0x52,0x89,0x2f,0xd9,0x95,0xd3,0x86,0x91,0x6a,0x4b,0x15,0x6f,0xd5,0x98,0x98,0xeb,0x3b,0xad,0x71,0xbe,0xf1,0x7e,0xcb,0xcc,0xe2,0xf2,0x9d,0x99,}, @@ -1325,6 +1326,35 @@ static const gsm_frame gsm_data_units[] = { {0xd0,0x5e,0x7b,0xe1,0x9a,0xa6,0x00,0x47,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0xb2,0x00,0x49,0x23,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,}, {0xd0,0xd9,0x92,0xa1,0x1a,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x54,0x00,0x49,0x24,0x92,0x49,0x24,}, }; +*/ +static const gsm_frame gsm_data_units[] = { // volt + {0xd2,0x55,0x62,0x58,0xda,0x50,0x00,0x59,0x77,0x9b,0xdd,0x33,0x70,0xa0,0xe7,0x1c,0xaa,0xb6,0xea,0x9c,0xc0,0xb8,0xd4,0x95,0x99,0x13,0xe2,0xc0,0xc4,0xe4,0x8c,0xc9,0x1b,}, + {0xd2,0x21,0xbb,0x69,0x63,0xd5,0x00,0xb9,0x1d,0x52,0x47,0x56,0xcd,0xa1,0x37,0xaf,0x72,0xa8,0xd2,0x56,0xe1,0x49,0x2c,0xb5,0xa2,0x40,0x57,0xc2,0xa9,0x25,0xb2,0xc6,0x80,}, + {0xd0,0xee,0xbb,0x21,0xeb,0x53,0x03,0xa9,0x27,0x6a,0xc8,0xaa,0x52,0xc2,0xcb,0xd9,0xa6,0xf8,0x78,0xa4,0xa4,0x17,0xdb,0x6a,0xd9,0x84,0x54,0xc4,0x97,0xd3,0x8a,0xc7,0x13,}, + {0xd0,0xf1,0xc2,0xe1,0xeb,0xa6,0x84,0x44,0xba,0x75,0xc7,0x62,0x52,0x82,0x32,0x7b,0x4e,0xbb,0x5b,0xa2,0xe1,0x10,0xf9,0x5d,0xcc,0xd3,0xa4,0xc1,0x10,0xf2,0x5d,0xcd,0x51,}, + {0xd3,0x98,0x8b,0x29,0xe3,0xa3,0xc4,0x26,0x96,0x93,0xdb,0xaa,0x53,0xa5,0x04,0x0d,0xca,0xe6,0xe1,0x53,0x04,0x18,0x44,0xee,0x7b,0x24,0xa7,0xf2,0x38,0xdc,0x8e,0x47,0x27,}, + {0xd3,0x2a,0xba,0xdc,0xa3,0x50,0x14,0x08,0xdb,0x91,0xc9,0x24,0x54,0xcc,0xc6,0x40,0xad,0xd7,0x6f,0xee,0x70,0x46,0x80,0xf1,0x55,0x35,0x53,0x4f,0xc7,0x09,0x9c,0xd6,0xf5,}, + {0xd3,0xed,0xb2,0x60,0x63,0x53,0x4d,0xc4,0xc8,0x3e,0x48,0x9e,0x53,0x8d,0xfb,0x0b,0x2f,0xba,0xe6,0x53,0xed,0xba,0x5b,0xd4,0xc8,0x67,0x53,0xce,0x9a,0xa4,0x8f,0x8c,0xad,}, + {0xd4,0x2d,0xc2,0x20,0x9b,0x53,0xb1,0x1a,0xdb,0x36,0x0e,0x95,0xa3,0xb0,0x2f,0x23,0x30,0x4e,0x64,0x52,0xd0,0xd9,0x22,0x63,0xe2,0xe4,0x53,0x2f,0x35,0x62,0x65,0x76,0xab,}, + {0xd3,0xf0,0xda,0x46,0xeb,0x51,0x4d,0x57,0xac,0x64,0x39,0x24,0xa0,0xcf,0x39,0xa5,0x48,0x49,0x25,0xa5,0x4d,0x97,0x65,0x4c,0xf3,0x23,0x53,0x0a,0x77,0x7a,0xa4,0x9e,0xa4,}, + {0xd4,0x2a,0xdb,0xc2,0xab,0x53,0x89,0xda,0xb3,0x89,0xae,0xcd,0x53,0x2c,0x49,0x2d,0x85,0x0e,0xdc,0xa3,0x0c,0x48,0xe5,0xad,0x91,0x9b,0xa3,0xac,0x48,0xa3,0x92,0xc1,0x23,}, + {0xd3,0x6d,0x9b,0x12,0x2c,0x53,0x4b,0x47,0x65,0x89,0x89,0x44,0xa5,0x69,0xc5,0x64,0x66,0x8e,0xc4,0xa5,0x4a,0xc6,0xed,0x51,0x95,0xdb,0x53,0xc8,0x47,0x63,0x8d,0xd3,0x84,}, + {0xd3,0x2f,0x8a,0x9d,0xac,0x53,0x08,0xf8,0xdd,0xe7,0x20,0x7a,0xa3,0x47,0xc7,0x2d,0x91,0xb0,0x3d,0xa5,0x09,0x38,0xe5,0x96,0x28,0x1d,0xa5,0xa6,0x2a,0xd4,0x75,0x2a,0xb9,}, + {0xd2,0xf0,0x8a,0x59,0x74,0x53,0xe9,0x56,0xdc,0x86,0x45,0xb9,0x53,0xe9,0x43,0x23,0x8a,0x29,0x68,0xa5,0x49,0x28,0x6c,0x92,0xb4,0xcf,0x53,0xe7,0x49,0x1b,0x94,0x48,0xb7,}, + {0xd3,0x6b,0xc3,0x0a,0x2d,0xa5,0x0b,0x29,0x23,0x72,0xc8,0xd0,0x53,0x49,0x27,0x64,0x96,0xda,0xc0,0xa3,0xe8,0x32,0xad,0x50,0x7d,0x18,0x53,0xec,0xc5,0x24,0xae,0x33,0x1f,}, + {0xd4,0xa4,0x93,0x99,0x99,0xa5,0x09,0x07,0x97,0xaa,0xd8,0x15,0xa6,0xa9,0x26,0xfd,0x6d,0xb9,0x36,0xa6,0x27,0xb0,0x54,0x72,0xc9,0x6d,0xaa,0x42,0x32,0x14,0x2e,0xdb,0xae,}, + {0xd5,0x1c,0x7b,0xa9,0x98,0xac,0x01,0x7a,0x94,0xad,0x39,0x7c,0xb4,0x20,0xfc,0x8d,0xcd,0x19,0xfa,0xa2,0xe0,0xa7,0xca,0xd1,0xa9,0x5a,0xab,0x40,0xd3,0x0c,0x96,0x49,0x1a,}, + {0xd7,0x9b,0x59,0xa5,0x5a,0xb8,0x80,0xb7,0x39,0x6d,0xc8,0xe6,0xe0,0xa0,0xad,0x39,0x66,0x37,0x1c,0xe2,0xa0,0xb6,0xe4,0x29,0x46,0x5b,0xaa,0x40,0x29,0xde,0x8e,0x46,0xec,}, + {0xd8,0xdd,0x5a,0x50,0xd9,0xde,0x80,0xba,0xe5,0x59,0xb6,0xe3,0x58,0xe0,0x53,0x7a,0xa8,0xb4,0xe4,0x5a,0xe0,0x1b,0xd1,0x49,0x25,0x1a,0xaa,0x80,0xc6,0xa3,0x85,0xd7,0x1a,}, + {0xd8,0x9d,0x59,0x91,0x12,0x76,0xa0,0x6a,0x92,0x8d,0x99,0x09,0x76,0xa0,0xba,0xb3,0x91,0xb9,0x63,0x62,0xa0,0x46,0xab,0xcd,0x47,0x01,0xc8,0xc0,0xd7,0x33,0x75,0xc4,0xdc,}, + {0xd4,0xd6,0x50,0xdd,0x12,0x78,0xc0,0xa4,0xe5,0x2e,0x38,0xa4,0x94,0x80,0x34,0xa2,0x36,0x45,0x22,0xf0,0xc0,0x49,0x27,0x55,0xa6,0xec,0xe0,0xa0,0x58,0x86,0xb0,0xcc,0xe3,}, + {0xd6,0xd9,0x49,0x19,0x51,0xd8,0xc0,0xc7,0x23,0x8e,0x22,0xe3,0x5e,0x80,0x25,0x6a,0x69,0xd9,0x93,0x8c,0xe0,0x56,0x7e,0x56,0xc8,0xd2,0x72,0x80,0x2f,0xce,0x6b,0x2f,0x63,}, + {0xd7,0x62,0x83,0x65,0xe2,0xcf,0xad,0x49,0x2f,0x07,0x99,0x6c,0x62,0x26,0xdc,0xc5,0x6a,0xc9,0x5b,0x92,0x29,0x4b,0x19,0x31,0xe9,0x10,0xee,0x24,0x05,0x1b,0xc5,0x42,0x8b,}, + {0xd8,0xde,0x52,0x04,0x98,0xae,0x20,0xe6,0x53,0x75,0x25,0x76,0xe2,0x41,0x4d,0x63,0x4f,0xdc,0xdd,0xec,0x41,0x57,0x2d,0x96,0xd6,0xdf,0xc9,0x41,0xe9,0x24,0x71,0x29,0x8f,}, + {0xd8,0xe4,0xf2,0x10,0xd9,0x5a,0x20,0xa3,0x4b,0x49,0xc7,0x23,0x74,0x20,0x48,0xd4,0x4e,0x38,0xdb,0xa0,0x20,0x38,0xe3,0x6d,0xb6,0xdb,0xf0,0x20,0x38,0xe3,0x6d,0xb6,0xdb,}, + {0xd0,0x9b,0x9a,0xe1,0x5a,0x80,0x00,0x36,0xdb,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,}, + {0xd0,0x9b,0x6b,0x65,0x9a,0x54,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,}, +}; const SayedTexts sayed_texts = { .nula = { gsm_data_nula, 22 }, .jedna = { gsm_data_jedna, 25 }, @@ -1364,5 +1394,6 @@ const SayedTexts sayed_texts = { .minus = { gsm_data_minus, 29 }, .point = { gsm_data_point, 29 }, .hafo = { gsm_data_hafo, 26 }, - .units = { gsm_data_units, 64 }, +//.units = { gsm_data_units, 64 }, + .units = { gsm_data_units, 26 }, }; diff --git a/V203/gsm/main.cpp b/V203/gsm/main.cpp index 695ad63..73658bf 100644 --- a/V203/gsm/main.cpp +++ b/V203/gsm/main.cpp @@ -2,24 +2,77 @@ #include "fifo.h" #include "player.h" #include "GsmDecoder.h" +#include "adcdma.h" +#include "oneway.h" +#include "gpio.h" //////////////////////////////////////////////////////// /* Demo, které jen počítá od 0 do 1000000. Výstup je PWM - * na pinech PA1/PA8 24kHz. Odvozeno a teploměru na + * na pinech PA1/PA8 24kHz. Odvozeno z teploměru na * https://github.com/Kizarm/TTSCP_Client/tree/main/kecal/stm * * Tohle se do CH32V003 prostě nevejde. + * 12.05.2024 předěláno na voltmetr. Algoritmus měření není + * moc dokonalý, ale funguje to. Pin ADC je PA2, tlačítko + * na PA1 proti 3.3V. Teploměr na čipu stojí za prd, muselo + * by se to individuálně kalibrovat (nehledě na oteplení čipu). */ //////////////////////////////////////////////////////// +class Meassure : public OneWay { + GpioClass buton; + FIFO fifo; + unsigned avg, old; + unsigned passcnt; + public: + explicit Meassure () noexcept : OneWay(), + buton (GPIOA,1,(GPIO_Speed_In | GPIO_UPDI_MPPO)), + fifo(), avg(0u), old(0u), passcnt(0u) { + buton.setPuPd(GPIO_PuPd_DOWN); + } + unsigned int Send (uint16_t * const ptr, const unsigned int len) override; + void out (); +}; +static inline unsigned absdiff (const unsigned a, const unsigned b) { + int d = a - b; + return d < 0 ? -d : +d; +} +//////////////////////////////////////////////////////// static PwmClass pwm; static FIFO fifo; static TextPlayer player (fifo); static GsmDecoder decoder(fifo); + +static AdcDma adc; +static Meassure meas; + int main () { - pwm.attach(decoder); - int pass = 0u; + pwm.attach (decoder); + adc.attach (meas); for (;;) { - player.say(pass++); - pwm.delay (); + meas.out(); } return 0; } +//////////////////////////////////////////////////////// +static constexpr unsigned BK = 3316u << 4; // Mělo by to být přesně 3300. +unsigned int Meassure::Send(uint16_t * const ptr, const unsigned int len) { + for (unsigned n=0; n> 16; + avg = (avg * 15 + mv) >> 4; // klouzavý průměr s postupným zapomínáním + } + fifo.Write (avg); + return 0; +} +void Meassure::out() { + unsigned t; + if (fifo.Read (t)) { + if (passcnt) { passcnt -= 1u; } else { + const unsigned delta = absdiff(t, old); + if (delta > 10 or buton) { + old = t; + player.say(old, 3); + player.say(sayed_texts.units); + passcnt = 10u; + } + } + } +}