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;
|
||||
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);
|
||||
};
|
||||
void SPI1_IRQHandler () {
|
||||
if (pSpiInstance) pSpiInstance->irq();
|
||||
void DMA1_Channel3_IRQHandler() { // transmit channel
|
||||
if (pSpiInstance) pSpiInstance->drq();
|
||||
}
|
||||
static constexpr unsigned FM = 1u; // 10 MHz
|
||||
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 {
|
||||
r.B.MODE4 = 3u; // 50 MHz
|
||||
r.B.CNF4 = 0u; // gen push - pull
|
||||
r.B.MODE5 = 3u; // 50 MHz
|
||||
r.B.CNF5 = 3u; // alt push - pull
|
||||
r.B.MODE4 = FM;
|
||||
r.B.CNF4 = 2u; // alt push - pull
|
||||
r.B.MODE5 = FM;
|
||||
r.B.CNF5 = 2u; // alt push - pull
|
||||
|
||||
r.B.MODE6 = 0u; // input mode
|
||||
r.B.CNF6 = 1u; // floating
|
||||
r.B.MODE7 = 3u; // 50 MHz
|
||||
r.B.CNF7 = 3u; // alt push - pull
|
||||
r.B.MODE7 = FM;
|
||||
r.B.CNF7 = 2u; // alt push - pull
|
||||
return r.R;
|
||||
});
|
||||
// AFIO - default
|
||||
}
|
||||
void SpiClass::irq() {
|
||||
if (SPI1.STATR.B.RXNE) {
|
||||
buffer [index++] = SPI1.DATAR.R;
|
||||
if (index == total) {
|
||||
void SpiClass::drq() {
|
||||
DMA1_Type::INTFR_DEF state (DMA1.INTFR);
|
||||
if (state.B.TCIF3) {
|
||||
DMA1.INTFCR.B.CTCIF3 = SET; // clear
|
||||
complete = true;
|
||||
index = 0u;
|
||||
select (true);
|
||||
return;
|
||||
}
|
||||
// tady by mělo být už odesláno
|
||||
SPI1.DATAR.R = buffer [index];
|
||||
DMA1.CFGR3.B.EN = RESET;
|
||||
SPI1.CTLR1.B.SPE = RESET;
|
||||
}
|
||||
}
|
||||
|
||||
SpiClass::SpiClass() noexcept : index(0u), total(0u), complete (false) {
|
||||
SpiClass::SpiClass() noexcept : total(0u), complete (true) {
|
||||
pSpiInstance = this;
|
||||
}
|
||||
void SpiClass::Init() {
|
||||
RCC.APB2PCENR.modify([](RCC_Type::APB2PCENR_DEF & r) -> uint32_t {
|
||||
r.B.SPI1EN = SET;
|
||||
r.B.IOPAEN = SET;
|
||||
r.B.AFIOEN = SET;
|
||||
return r.R;
|
||||
});
|
||||
RCC.AHBPCENR.B.DMA1EN = SET;
|
||||
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 {
|
||||
r.B.CPHA = 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 {
|
||||
r.B.SSOE = SET;
|
||||
r.B.RXNEIE = SET;
|
||||
//r.B.RXNEIE = SET;
|
||||
//r.B.TXEIE = SET;
|
||||
r.B.TXDMAEN = SET;
|
||||
return r.R;
|
||||
});
|
||||
NVIC.EnableIRQ(SPI1_IRQn);
|
||||
SPI1.CTLR1.B.SPE = SET;
|
||||
NVIC.EnableIRQ(DMA1_Channel3_IRQn);
|
||||
}
|
||||
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) {
|
||||
if (!complete) return false;
|
||||
select (false);
|
||||
complete = false;
|
||||
index = 0u;
|
||||
total = len > SPIBUFLEN ? SPIBUFLEN : len;
|
||||
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;
|
||||
}
|
||||
char * SpiClass::received (unsigned int & count) {
|
||||
if (complete) count = total;
|
||||
else count = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
#ifndef SPICLASS_H
|
||||
#define SPICLASS_H
|
||||
|
||||
/**
|
||||
*/
|
||||
static constexpr unsigned SPIBUFLEN = 8u;
|
||||
|
||||
class SpiClass {
|
||||
volatile unsigned index;
|
||||
unsigned total;
|
||||
volatile bool complete;
|
||||
char buffer [SPIBUFLEN];
|
||||
public:
|
||||
explicit SpiClass () noexcept;
|
||||
void irq ();
|
||||
void select (const bool set) const noexcept;
|
||||
void Init ();
|
||||
void drq ();
|
||||
bool send (const char * data, const unsigned len);
|
||||
char * received (unsigned & count);
|
||||
protected:
|
||||
// void select (const bool set) const noexcept;
|
||||
};
|
||||
|
||||
#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),
|
||||
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),
|
||||
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;
|
||||
void write (DATA_BLOCK const * data);
|
||||
void pass ();
|
||||
|
|
Loading…
Reference in a new issue