add adc process

This commit is contained in:
Kizarm 2024-03-04 11:23:10 +01:00
parent fc31db365d
commit a4c3361300
4 changed files with 58 additions and 24 deletions

View file

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

View file

@ -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 ();

View file

@ -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<uint16_t, 8> 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<len; n++) sum += ptr [n];
sum >>= 4;
data.Write (static_cast<uint16_t> (sum));
return len;
}
void pass () {
uint16_t avg;
if (!data.Read (avg)) return;
cout << "pass: " << pass_cnt << ", avg = " << static_cast<int>(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;
}

View file

@ -32,7 +32,7 @@ struct NVIC_Type {
IRER [((uint32_t)(IRQ) >> 5)] = (1 << ((uint32_t)(IRQ) & 0x1F));
}
};
NVIC_Type & NVIC = * reinterpret_cast<NVIC_Type * const> (0xE000E000);
static NVIC_Type & NVIC = * reinterpret_cast<NVIC_Type * const> (0xE000E000);
struct SysTick_Type {
union CTLR_DEF {
struct {
@ -68,6 +68,6 @@ struct SysTick_Type {
NVIC.EnableIRQ (SysTicK_IRQn);
}
};
SysTick_Type & SysTick = * reinterpret_cast<SysTick_Type * const> (0xE000F000);
static SysTick_Type & SysTick = * reinterpret_cast<SysTick_Type * const> (0xE000F000);
#endif // SYSTEM_H