This commit is contained in:
Kizarm 2024-03-03 21:25:22 +01:00
parent d625547fb6
commit fc31db365d
6 changed files with 201 additions and 0 deletions

54
adc/Makefile Normal file
View file

@ -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

112
adc/adcclass.cpp Normal file
View file

@ -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<size_t> (& ADC1.RDATAR);
// Configure the memory address
DMA1.MADDR1.R = reinterpret_cast<size_t> (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);
}

21
adc/adcclass.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef ADCCLASS_H
#define ADCCLASS_H
#include <stdint.h>
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

1
adc/ch32v003 Symbolic link
View file

@ -0,0 +1 @@
../ch32v003/

1
adc/common Symbolic link
View file

@ -0,0 +1 @@
../common/

12
adc/main.cpp Normal file
View file

@ -0,0 +1,12 @@
#include "gpio.h"
#include "usartclass.h"
#include "print.h"
#include "adcclass.h"
//////////////////////////////////////
//////////////////////////////////////
static AdcClass adc;
int main () {
for (;;) {
}
return 0;
}