spi add tx dma

This commit is contained in:
Kizarm 2024-11-09 16:26:15 +01:00
parent 64aeaf99ed
commit 4ac7016ea1
3 changed files with 55 additions and 46 deletions

View file

@ -15,52 +15,72 @@ enum SPICLK : uint32_t {
static SpiClass * pSpiInstance = nullptr; static SpiClass * pSpiInstance = nullptr;
extern "C" { extern "C" {
[[gnu::interrupt]] extern void SPI1_IRQHandler (); //[[gnu::interrupt]] extern void DMA1_Channel2_IRQHandler();
[[gnu::interrupt]] extern void DMA1_Channel3_IRQHandler();
extern void * memcpy (void * dest, const void * src, size_t n); extern void * memcpy (void * dest, const void * src, size_t n);
}; };
void SPI1_IRQHandler () { void DMA1_Channel3_IRQHandler() { // transmit channel
if (pSpiInstance) pSpiInstance->irq(); if (pSpiInstance) pSpiInstance->drq();
} }
static constexpr unsigned FM = 1u; // 10 MHz
static void InitPins () noexcept { static void InitPins () noexcept {
// PA4 - NSS (software), PA5 - SCK, PA6 - MISO, PA7 - MOSI // PA4 - NSS, PA5 - SCK, PA6 - MISO, PA7 - MOSI
GPIOA.CFGLR.modify([](GPIOA_Type::CFGLR_DEF & r) -> uint32_t { GPIOA.CFGLR.modify([](GPIOA_Type::CFGLR_DEF & r) -> uint32_t {
r.B.MODE4 = 3u; // 50 MHz r.B.MODE4 = FM;
r.B.CNF4 = 0u; // gen push - pull r.B.CNF4 = 2u; // alt push - pull
r.B.MODE5 = 3u; // 50 MHz r.B.MODE5 = FM;
r.B.CNF5 = 3u; // alt push - pull r.B.CNF5 = 2u; // alt push - pull
r.B.MODE6 = 0u; // input mode r.B.MODE6 = 0u; // input mode
r.B.CNF6 = 1u; // floating r.B.CNF6 = 1u; // floating
r.B.MODE7 = 3u; // 50 MHz r.B.MODE7 = FM;
r.B.CNF7 = 3u; // alt push - pull r.B.CNF7 = 2u; // alt push - pull
return r.R; return r.R;
}); });
// AFIO - default // AFIO - default
} }
void SpiClass::irq() { void SpiClass::drq() {
if (SPI1.STATR.B.RXNE) { DMA1_Type::INTFR_DEF state (DMA1.INTFR);
buffer [index++] = SPI1.DATAR.R; if (state.B.TCIF3) {
if (index == total) { DMA1.INTFCR.B.CTCIF3 = SET; // clear
complete = true; complete = true;
index = 0u; DMA1.CFGR3.B.EN = RESET;
select (true); SPI1.CTLR1.B.SPE = RESET;
return;
}
// tady by mělo být už odesláno
SPI1.DATAR.R = buffer [index];
} }
} }
SpiClass::SpiClass() noexcept : index(0u), total(0u), complete (false) { SpiClass::SpiClass() noexcept : total(0u), complete (true) {
pSpiInstance = this; pSpiInstance = this;
}
void SpiClass::Init() {
RCC.APB2PCENR.modify([](RCC_Type::APB2PCENR_DEF & r) -> uint32_t { RCC.APB2PCENR.modify([](RCC_Type::APB2PCENR_DEF & r) -> uint32_t {
r.B.SPI1EN = SET; r.B.SPI1EN = SET;
r.B.IOPAEN = SET; r.B.IOPAEN = SET;
r.B.AFIOEN = SET; r.B.AFIOEN = SET;
return r.R; return r.R;
}); });
RCC.AHBPCENR.B.DMA1EN = SET;
InitPins(); InitPins();
select (true); // Configure the peripheral data register address
DMA1.PADDR3.R = reinterpret_cast<size_t> (& SPI1.DATAR);
// Configure the memory address
DMA1.MADDR3.R = reinterpret_cast<size_t> (buffer);
// Configure the number of DMA tranfer to be performs on DMA channel 1
// DMA1.CNTR3 .R = FULL_LEN;
// Configure increment, size, interrupts and circular mode
DMA1.CFGR3.modify([] (DMA1_Type::CFGR3_DEF & r) -> uint32_t {
r.B.PL = 3u; // highest priority
r.B.DIR = SET; // memory -> periferal
r.B.MINC = SET; // memory increment
r.B.MSIZE = 0u; // 8-bit
r.B.PSIZE = 0u; // 8-bit
//r.B.HTIE = SET; // INT Enable HALF
r.B.TCIE = SET; // INT Enable FULL
r.B.CIRC = RESET; // ! Circular MODE
//Enable DMA Channel 1
//r.B.EN = SET;
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 = SET;
r.B.CPOL = SET; r.B.CPOL = SET;
@ -74,31 +94,21 @@ SpiClass::SpiClass() noexcept : index(0u), total(0u), complete (false) {
}); });
SPI1.CTLR2.modify([](SPI1_Type::CTLR2_DEF & r) -> uint32_t { SPI1.CTLR2.modify([](SPI1_Type::CTLR2_DEF & r) -> uint32_t {
r.B.SSOE = SET; r.B.SSOE = SET;
r.B.RXNEIE = SET; //r.B.RXNEIE = SET;
//r.B.TXEIE = SET;
r.B.TXDMAEN = SET;
return r.R; return r.R;
}); });
NVIC.EnableIRQ(SPI1_IRQn); NVIC.EnableIRQ(DMA1_Channel3_IRQn);
SPI1.CTLR1.B.SPE = SET;
} }
void SpiClass::select (const bool set) const noexcept {
if (set) GPIOA.BSHR.B.BS4 = SET;
else GPIOA.BSHR.B.BR4 = SET;
}
bool SpiClass::send (const char * data, const unsigned int len) { bool SpiClass::send (const char * data, const unsigned int len) {
if (!complete) return false; if (!complete) return false;
select (false);
complete = false; complete = false;
index = 0u;
total = len > SPIBUFLEN ? SPIBUFLEN : len; total = len > SPIBUFLEN ? SPIBUFLEN : len;
memcpy (buffer, data, total); memcpy (buffer, data, total);
SPI1.DATAR.R = buffer [index]; DMA1.CNTR3.R = total;
DMA1.CFGR3.B.EN = SET;
SPI1.CTLR1.B.SPE = SET;
return true; return true;
} }
char * SpiClass::received (unsigned int & count) {
if (complete) count = total;
else count = 0;
return buffer;
}

View file

@ -1,21 +1,20 @@
#ifndef SPICLASS_H #ifndef SPICLASS_H
#define SPICLASS_H #define SPICLASS_H
/** /**
*/ */
static constexpr unsigned SPIBUFLEN = 8u; static constexpr unsigned SPIBUFLEN = 8u;
class SpiClass { class SpiClass {
volatile unsigned index;
unsigned total; unsigned total;
volatile bool complete; volatile bool complete;
char buffer [SPIBUFLEN]; char buffer [SPIBUFLEN];
public: public:
explicit SpiClass () noexcept; explicit SpiClass () noexcept;
void irq (); void Init ();
void select (const bool set) const noexcept; void drq ();
bool send (const char * data, const unsigned len); bool send (const char * data, const unsigned len);
char * received (unsigned & count); protected:
// void select (const bool set) const noexcept;
}; };
#endif // SPICLASS_H #endif // SPICLASS_H

View file

@ -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) {}; rcvd_counter(0u), rcvd_status (RCVD_IDLE) { spi.Init(); };
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 ();