#include "system.h" #include "spiclass.h" typedef __SIZE_TYPE__ size_t; enum SPICLK : uint32_t { FPCLK_2 = 0u, // 72 MHz FPCLK_4, // 72 MHz FPCLK_8, // 36 MHz FPCLK_16, // 18 MHz FPCLK_32, // 9 MHz FPCLK_64, // 4.5 MHz FPCLK_128, // 2.25 MHz FPCLK_256, // 1.125 MHz }; static SpiClass * pSpiInstance = nullptr; extern "C" { [[gnu::interrupt]] extern void SPI1_IRQHandler (); extern void * memcpy (void * dest, const void * src, size_t n); }; void SPI1_IRQHandler () { if (pSpiInstance) pSpiInstance->irq(); } static void InitPins () noexcept { // PA4 - NSS (software), 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.MODE6 = 0u; // input mode r.B.CNF6 = 1u; // floating r.B.MODE7 = 3u; // 50 MHz r.B.CNF7 = 3u; // 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]; } } SpiClass::SpiClass() noexcept : index(0u), total(0u), complete (false) { pSpiInstance = this; 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; }); InitPins(); select (true); SPI1.CTLR1.modify([](SPI1_Type::CTLR1_DEF & r) -> uint32_t { r.B.CPHA = SET; r.B.CPOL = SET; r.B.MSTR = SET; r.B.DFF = RESET; // 8 bit r.B.SSM = SET; r.B.SSI = SET; r.B.LSBFIRST = RESET; r.B.BR = FPCLK_64; // 4.5 MHz return r.R; }); SPI1.CTLR2.modify([](SPI1_Type::CTLR2_DEF & r) -> uint32_t { r.B.SSOE = SET; r.B.RXNEIE = SET; return r.R; }); NVIC.EnableIRQ(SPI1_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) { if (!complete) return false; select (false); complete = false; index = 0u; total = len > SPIBUFLEN ? SPIBUFLEN : len; memcpy (buffer, data, total); SPI1.DATAR.R = buffer [index]; return true; } char * SpiClass::received (unsigned int & count) { if (complete) count = total; else count = 0; return buffer; }