From fc31db365de4ca6036c6546b061bda513bba11b6 Mon Sep 17 00:00:00 2001 From: Kizarm Date: Sun, 3 Mar 2024 21:25:22 +0100 Subject: [PATCH] add adc --- adc/Makefile | 54 +++++++++++++++++++++++ adc/adcclass.cpp | 112 +++++++++++++++++++++++++++++++++++++++++++++++ adc/adcclass.h | 21 +++++++++ adc/ch32v003 | 1 + adc/common | 1 + adc/main.cpp | 12 +++++ 6 files changed, 201 insertions(+) create mode 100644 adc/Makefile create mode 100644 adc/adcclass.cpp create mode 100644 adc/adcclass.h create mode 120000 adc/ch32v003 create mode 120000 adc/common create mode 100644 adc/main.cpp diff --git a/adc/Makefile b/adc/Makefile new file mode 100644 index 0000000..1380a0b --- /dev/null +++ b/adc/Makefile @@ -0,0 +1,54 @@ +# ch32v003 +TARGET?= ch32v003 +TOOL ?= gcc + +PRJ = example + +VPATH = . ./$(TARGET) ./common +BLD = ./build/ +DFLAGS = -d +LFLAGS = -g +LDLIBS = +BFLAGS = --strip-unneeded + +CFLAGS = -MMD -Wall -ggdb -fno-exceptions -ffunction-sections -fdata-sections +CFLAGS+= -I. -I./common -I./$(TARGET) -I/usr/include/newlib +DEL = rm -f + +# zdrojaky +OBJS = main.o adcclass.o +#OBJS += usartclass.o print.o + +include $(TARGET)/$(TOOL).mk +BOBJS = $(addprefix $(BLD),$(OBJS)) + +all: $(BLD) $(PRJ).elf +# ... atd. +-include $(BLD)*.d +# linker +$(PRJ).elf: $(BOBJS) + -@echo [LD $(TOOL),$(TARGET)] $@ + @$(LD) $(LFLAGS) -o $(PRJ).elf $(BOBJS) $(LDLIBS) + -@echo "size:" + @$(SIZE) $(PRJ).elf + -@echo "listing:" + $(DUMP) $(DFLAGS) $(PRJ).elf > $(PRJ).lst + -@echo "OK." + $(COPY) $(BFLAGS) -O binary $(PRJ).elf $(PRJ).bin +# preloz co je potreba +$(BLD)%.o: %.c + -@echo [CC $(TOOL),$(TARGET)] $@ + @$(CC) -c $(CFLAGS) $< -o $@ +$(BLD)%.o: %.cpp + -@echo [CX $(TOOL),$(TARGET)] $@ + @$(CXX) -std=c++17 -fno-rtti -c $(CFLAGS) $< -o $@ +$(BLD): + mkdir $(BLD) +sin.c: sin.py + ./sin.py +flash: $(PRJ).elf + minichlink -w $(PRJ).bin flash -b +# vycisti +clean: + $(DEL) $(BLD)* *.lst *.bin *.elf *.map sin.c *~ +.PHONY: all clean diff --git a/adc/adcclass.cpp b/adc/adcclass.cpp new file mode 100644 index 0000000..9a024e2 --- /dev/null +++ b/adc/adcclass.cpp @@ -0,0 +1,112 @@ +#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); +} + +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 + GPIOC + RCC.APB2PCENR.modify([](RCC_Type::APB2PCENR_DEF & r) -> auto { + r.B.ADC1EN = SET; + r.B.IOPCEN = SET; + return r.R; + }); + RCC.APB1PCENR.B.TIM2EN = SET; // Enable TIM2 + RCC.CFGR0.B.ADCPRE = 0u; // 000xx: AHBCLK divided by 2 as ADC clock (24 MHz max). + // PIN PC4 / A2 + GPIOC.CFGLR.modify([](GPIOA_Type::CFGLR_DEF & r) -> auto { + r.B.MODE4 = 0u; + r.B.CNF4 = 0u; + return r.R; + }); +} +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; +} +static inline void AdcCalibrate (void) noexcept { + ADC1.RSQR3.B.SQ1 = 1u; // CH1 + ADC1.RSQR1.B.L = 0u; // 1 regular conversion + ADC1.SAMPTR2_CHARGE2.B.SMP1_TKCG1 = 7u; + ADC1.CTLR1.B.SCAN = SET; + + ADC1.CTLR2.B.ADON = 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 + ADC1.CTLR2.B.ADON = RESET; +} +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); + // 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 = 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; + // 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 = 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 (); + Timer2Init (1000u); + NVIC.EnableIRQ (DMA1_Channel1_IRQn); + AdcCalibrate(); + Dma1Ch1Init (buffer); + AdcPostInit (); + // start timer + TIM2.CTLR1.B.CEN = SET; +} +inline void AdcClass::send(const bool b) { + if (!dst) return; + if (b) dst->Send (pH, HALF_LEN); + else dst->Send (pL, HALF_LEN); +} diff --git a/adc/adcclass.h b/adc/adcclass.h new file mode 100644 index 0000000..4f2096f --- /dev/null +++ b/adc/adcclass.h @@ -0,0 +1,21 @@ +#ifndef ADCCLASS_H +#define ADCCLASS_H +#include + +class OneWay; +static constexpr unsigned HALF_LEN = 64u; +static constexpr unsigned FULL_LEN = HALF_LEN * 2u; + +class AdcClass { + uint16_t * pL; + uint16_t * pH; + uint16_t buffer [FULL_LEN]; + OneWay * dst; + public: + explicit AdcClass () noexcept; + void attach (OneWay & d) { dst = & d; } + void send (const bool b); + +}; + +#endif // ADCCLASS_H diff --git a/adc/ch32v003 b/adc/ch32v003 new file mode 120000 index 0000000..0bcf9a1 --- /dev/null +++ b/adc/ch32v003 @@ -0,0 +1 @@ +../ch32v003/ \ No newline at end of file diff --git a/adc/common b/adc/common new file mode 120000 index 0000000..8332399 --- /dev/null +++ b/adc/common @@ -0,0 +1 @@ +../common/ \ No newline at end of file diff --git a/adc/main.cpp b/adc/main.cpp new file mode 100644 index 0000000..ffb9622 --- /dev/null +++ b/adc/main.cpp @@ -0,0 +1,12 @@ +#include "gpio.h" +#include "usartclass.h" +#include "print.h" +#include "adcclass.h" +////////////////////////////////////// +////////////////////////////////////// +static AdcClass adc; +int main () { + for (;;) { + } + return 0; +}