Compare commits

..

3 commits

Author SHA1 Message Date
Kizarm
a5bfd0e961 small change 2025-01-05 11:49:29 +01:00
Kizarm
84be40e742 small repair 2024-11-30 11:03:21 +01:00
Kizarm
b12b9b92af change spi to soft 2024-11-26 17:37:48 +01:00
10 changed files with 87 additions and 29 deletions

1
.gitignore vendored
View file

@ -24,4 +24,5 @@ V203/usb/scope/software/moc/*
V203/usb/scope/software/obj/* V203/usb/scope/software/obj/*
V203/usb/scope/software/qrc_src.cpp V203/usb/scope/software/qrc_src.cpp
V203/usb/scope/software/ui_mainwindow.h V203/usb/scope/software/ui_mainwindow.h
V203/usb/spitest/*

View file

@ -69,12 +69,18 @@ static inline void AdcCalibrate (void) noexcept {
RCC.APB2PRSTR.B.ADC1RST = SET; RCC.APB2PRSTR.B.ADC1RST = SET;
RCC.APB2PRSTR.B.ADC1RST = RESET; RCC.APB2PRSTR.B.ADC1RST = RESET;
// set channels // set channels
ADC1.RSQR3__CHANNEL.B.SQ1__CHSEL = 0u; // CH0 ADC1.RSQR3__CHANNEL.modify([](ADC1_Type::RSQR3__CHANNEL_DEF & r) -> auto {
ADC1.RSQR3__CHANNEL.B.SQ2 = 1u; // CH1 r.B.SQ1__CHSEL = 0u; // CH0
r.B.SQ2 = 1u; // CH1
return r.R;
});
ADC1.RSQR1.B.L = ADC_MAXCHANNELS - 1U; // 2 regular conversion ADC1.RSQR1.B.L = ADC_MAXCHANNELS - 1U; // 2 regular conversion
static constexpr unsigned ts = 0u; ADC1.SAMPTR2_CHARGE2.modify([](ADC1_Type::SAMPTR2_CHARGE2_DEF & r) -> auto {
ADC1.SAMPTR2_CHARGE2.B.SMP2_TKCG2 = ts; static constexpr unsigned ts = 0u;
ADC1.SAMPTR2_CHARGE2.B.SMP3_TKCG3 = ts; r.B.SMP0_TKCG0 = ts;
r.B.SMP1_TKCG1 = ts;
return r.R;
});
ADC1.CTLR1.B.SCAN = SET; ADC1.CTLR1.B.SCAN = SET;
ADC1.CTLR2.B.ADON = SET; ADC1.CTLR2.B.ADON = SET;

View file

@ -33,13 +33,23 @@ class GpioClass {
//r.B.IOPCEN = SET; //r.B.IOPCEN = SET;
return r.R; return r.R;
}); });
const uint32_t pos = pin << 2; if (pin < 8u) {
port.CFGLR.modify([=](GPIOA_Type::CFGLR_DEF & r)->auto { const uint32_t pos = pin << 2;
uint32_t t = r.R; port.CFGLR.modify([=](GPIOA_Type::CFGLR_DEF & r)->auto {
t &= ~(0xFu << pos); uint32_t t = r.R;
t |= _mode << pos; t &= ~(0xFu << pos);
return t; t |= _mode << pos;
}); return t;
});
} else {
const uint32_t pos = (pin - 8u) << 2;
port.CFGHR.modify([=](GPIOA_Type::CFGHR_DEF & r)->auto {
uint32_t t = r.R;
t &= ~(0xFu << pos);
t |= _mode << pos;
return t;
});
}
} }
void operator<< (const bool b) const { void operator<< (const bool b) const {
port.BSHR.R = b ? 1u << pin : 1u << (pin + 16); port.BSHR.R = b ? 1u << pin : 1u << (pin + 16);

View file

@ -82,14 +82,14 @@ void SpiClass::Init() {
return r.R; return r.R;
}); });
SPI1.CTLR1.modify([](SPI1_Type::CTLR1_DEF & r) -> uint32_t { SPI1.CTLR1.modify([](SPI1_Type::CTLR1_DEF & r) -> uint32_t {
r.B.CPHA = SET; r.B.CPHA = RESET;
r.B.CPOL = SET; r.B.CPOL = RESET;
r.B.MSTR = SET; r.B.MSTR = SET;
r.B.DFF = RESET; // 8 bit r.B.DFF = RESET; // 8 bit
r.B.SSM = SET; r.B.SSM = SET;
r.B.SSI = SET; r.B.SSI = SET;
r.B.LSBFIRST = RESET; r.B.LSBFIRST = SET;
r.B.BR = FPCLK_64; // 4.5 MHz r.B.BR = FPCLK_32; // 4.5 MHz
return r.R; return r.R;
}); });
SPI1.CTLR2.modify([](SPI1_Type::CTLR2_DEF & r) -> uint32_t { SPI1.CTLR2.modify([](SPI1_Type::CTLR2_DEF & r) -> uint32_t {
@ -106,6 +106,8 @@ bool SpiClass::send (const char * data, const unsigned int len) {
complete = false; complete = false;
total = len > SPIBUFLEN ? SPIBUFLEN : len; total = len > SPIBUFLEN ? SPIBUFLEN : len;
memcpy (buffer, data, total); memcpy (buffer, data, total);
DMA1.PADDR3.R = reinterpret_cast<size_t> (& SPI1.DATAR);
DMA1.MADDR3.R = reinterpret_cast<size_t> (buffer);
DMA1.CNTR3.R = total; DMA1.CNTR3.R = total;
DMA1.CFGR3.B.EN = SET; DMA1.CFGR3.B.EN = SET;
SPI1.CTLR1.B.SPE = SET; SPI1.CTLR1.B.SPE = SET;

View file

@ -0,0 +1,22 @@
#include "spisim.h"
#include "system.h"
SpiSim::SpiSim() noexcept : nss(GPIOA,4), sck(GPIOA,5), mosi(GPIOA,7) {
delay_init();
nss << true;
sck << false;
mosi << false;
}
void SpiSim::outbyte(const uint8_t b) const {
nss << false;
for (unsigned n=0u; n<8; n++) {
const bool bit = (b & (1u << n)) ? true : false;
mosi << bit;
delay_us (2);
sck << true;
delay_us (4);
sck << false;
delay_us (2);
}
nss << true;
}

View file

@ -0,0 +1,17 @@
#ifndef SPISIM_H
#define SPISIM_H
#include "gpio.h"
/** Původní třída SpiClass s DMA a hardware SPI se chová divně
* a je zbytečně složitá. Zde je potřeba odeslat 1 Byte na obvod
* 74595 a je jednodušší to udělat softwarově. Výstup je sice
* blokující, ale ten byte je dost krátká doba, aby to nerušilo.
*/
class SpiSim {
GpioClass nss, sck, mosi;
public:
explicit SpiSim () noexcept;
void outbyte (const uint8_t b) const;
};
#endif // SPISIM_H

View file

@ -17,7 +17,7 @@ DEL = rm -f
# zdrojaky # zdrojaky
OBJS = main.o hack.o OBJS = main.o hack.o
OBJS += usb_desc.o cdc_class.o spiclass.o adcscope.o samplering.o OBJS += usb_desc.o cdc_class.o spisim.o adcscope.o samplering.o
include $(TARGET)/$(TOOL).mk include $(TARGET)/$(TOOL).mk
BOBJS = $(addprefix $(BLD),$(OBJS)) BOBJS = $(addprefix $(BLD),$(OBJS))

View file

@ -76,11 +76,11 @@ void SampleRing::CommandPass(const unsigned int cmd) {
switch (dest) { switch (dest) {
case DEST_CHA: case DEST_CHA:
voltage.a = header.bits.cmd_value; voltage.a = header.bits.cmd_value;
spi.send (voltage.common, 1); spi.outbyte (voltage.common[0]);
break; break;
case DEST_CHB: case DEST_CHB:
voltage.b = header.bits.cmd_value; voltage.b = header.bits.cmd_value;
spi.send (voltage.common, 1); spi.outbyte (voltage.common[0]);
break; break;
case DEST_BASE: case DEST_BASE:
m_time_base_order = header.bits.cmd_value; m_time_base_order = header.bits.cmd_value;

View file

@ -3,7 +3,7 @@
#include <stdint.h> #include <stdint.h>
#include "structures.h" #include "structures.h"
#include "baselayer.h" #include "baselayer.h"
#include "spiclass.h" #include "spisim.h"
static constexpr unsigned RING_BIT = 10; static constexpr unsigned RING_BIT = 10;
static constexpr unsigned RING_LEN = 1u << RING_BIT; static constexpr unsigned RING_LEN = 1u << RING_BIT;
@ -19,7 +19,7 @@ enum RCVD_STATUS {
}; };
class SampleRing : public BaseLayer { class SampleRing : public BaseLayer {
SpiClass spi; SpiSim spi;
ChannelVoltage voltage; ChannelVoltage voltage;
[[gnu::aligned(4)]]DATA_BLOCK ring_buffer [RING_LEN]; [[gnu::aligned(4)]]DATA_BLOCK ring_buffer [RING_LEN];
TrigerSettings m_settings; TrigerSettings m_settings;
@ -38,7 +38,7 @@ class SampleRing : public BaseLayer {
explicit SampleRing () noexcept : BaseLayer(), spi(), voltage(), m_settings(), m_head(0), m_tail(0), m_lenght(0), explicit SampleRing () noexcept : BaseLayer(), spi(), voltage(), m_settings(), m_head(0), m_tail(0), m_lenght(0),
m_old_triger(false), m_trigered(false), m_finished(false), m_old_triger(false), m_trigered(false), m_finished(false),
m_mode (TIME_BASE_TRIGERED), o_mode (TIME_BASE_TRIGERED), m_time_base_order(6u), m_mode (TIME_BASE_TRIGERED), o_mode (TIME_BASE_TRIGERED), m_time_base_order(6u),
rcvd_counter(0u), rcvd_status (RCVD_IDLE) { spi.Init(); }; rcvd_counter(0u), rcvd_status (RCVD_IDLE) { };
uint32_t Up (const char * data, const uint32_t len) override; uint32_t Up (const char * data, const uint32_t len) override;
void write (DATA_BLOCK const * data); void write (DATA_BLOCK const * data);
void pass (); void pass ();

View file

@ -28,16 +28,16 @@ struct TrigerSettings {
}; };
static_assert (sizeof(TrigerSettings) == 10, "TrigerSettings error"); static_assert (sizeof(TrigerSettings) == 10, "TrigerSettings error");
enum VOLTAGE_SCALE { enum VOLTAGE_SCALE {
S100mV = 0b0011, // 1:1 x10 S100mV = 0b1100, // 1:1 x10
S200mV = 0b0111, // 1:1 x5 S200mV = 0b1110, // 1:1 x5
S500mV = 0b1011, // 1:1 x2 S500mV = 0b1101, // 1:1 x2
S1V = 0b0000, // 1:10 x10 S1V = 0b0000, // 1:10 x10
S2V = 0b0100, // 1:10 x5 S2V = 0b0010, // 1:10 x5
S5V = 0b1000, // 1:10 x2 S5V = 0b0001, // 1:10 x2
S10V = 0b0001, // 1:100x10 S10V = 0b1000, // 1:100x10
S20V = 0b0101, // 1:100x5 S20V = 0b1010, // 1:100x5
S50V = 0b1001, // 1:100x2 S50V = 0b1001, // 1:100x2
}; };
union ChannelVoltage { union ChannelVoltage {