diff --git a/V203/usb/ch32v203/spiclass.cpp b/V203/usb/ch32v203/spiclass.cpp index 1d864e0..05885ec 100644 --- a/V203/usb/ch32v203/spiclass.cpp +++ b/V203/usb/ch32v203/spiclass.cpp @@ -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) { - complete = true; - index = 0u; - select (true); - return; - } - // tady by mělo být už odesláno - SPI1.DATAR.R = buffer [index]; +void SpiClass::drq() { + DMA1_Type::INTFR_DEF state (DMA1.INTFR); + if (state.B.TCIF3) { + DMA1.INTFCR.B.CTCIF3 = SET; // clear + complete = true; + 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 (& SPI1.DATAR); + // Configure the memory address + DMA1.MADDR3.R = reinterpret_cast (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; -} diff --git a/V203/usb/ch32v203/spiclass.h b/V203/usb/ch32v203/spiclass.h index 8b6c80b..fb9637e 100644 --- a/V203/usb/ch32v203/spiclass.h +++ b/V203/usb/ch32v203/spiclass.h @@ -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 diff --git a/V203/usb/scope/firmware/samplering.h b/V203/usb/scope/firmware/samplering.h index 7043b88..53581bf 100644 --- a/V203/usb/scope/firmware/samplering.h +++ b/V203/usb/scope/firmware/samplering.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 ();