spi add tx dma
This commit is contained in:
parent
64aeaf99ed
commit
4ac7016ea1
3 changed files with 55 additions and 46 deletions
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
Loading…
Reference in a new issue