#include "system.h" #include "usart.h" static Usart * pInstance = nullptr; static constexpr unsigned HCLK = 48'000'000u; extern "C" void USART1_IRQHandler (void) __attribute__((interrupt)); void USART1_IRQHandler (void) { if (pInstance) pInstance->irq(); }; Usart::Usart(const uint32_t _baud) noexcept : BaseLayer (), tx_ring () { pInstance = this; // 1. Clock Enable RCC.APB2PCENR.modify([](RCC_Type::APB2PCENR_DEF & r) -> auto { r.B.USART1EN = SET; r.B.IOPDEN = SET; return r.R; }); // 2. GPIO Alternate Config - default TX/PD5, RX/PD6 GPIOD.CFGLR.modify([](GPIOA_Type::CFGLR_DEF & r) -> auto { r.B.MODE5 = 1u; r.B.CNF5 = 2u; // or 3u for open drain r.B.MODE6 = 0u; r.B.CNF6 = 1u; // floating input return r.R; }); // 4. NVIC NVIC.EnableIRQ (USART1_IRQn); // 5. USART registry 8.bit bez parity USART1.CTLR1.modify([] (USART1_Type::CTLR1_DEF & r) -> auto { r.B.RE = SET; r.B.TE = SET; r.B.RXNEIE = SET; return r.R; }); USART1.CTLR2.R = 0; //USART1.CTLR3.B.OVRDIS = SET; const uint32_t tmp = HCLK / _baud; USART1.BRR.R = tmp; USART1.CTLR1.B.UE = SET; // nakonec povolit globálně } void Usart::irq () { volatile USART1_Type::STATR_DEF status (USART1.STATR); // načti status přerušení char rdata, tdata; if (status.B.TXE) { // od vysílače if (tx_ring.Read (tdata)) { // pokud máme data USART1.DATAR.B.DR = (uint8_t) tdata; // zapíšeme do výstupu } else { // pokud ne // Předpoklad je half-duplex i.e. RS485, jinak jen zakázat TXEIE rdata = (USART1.DATAR.B.DR); // dummy read USART1.CTLR1.modify([](USART1_Type::CTLR1_DEF & r) -> auto { r.B.RE = SET; // povol prijem r.B.TXEIE = RESET; // je nutné zakázat přerušení od vysílače return r.R; }); } } if (status.B.RXNE) { // od přijímače rdata = (USART1.DATAR.B.DR); // načteme data Up (&rdata, 1u); // a pošleme dál } } uint32_t Usart::Down(const char * data, const uint32_t len) { unsigned n = 0u; for (n=0u; n auto { r.B.RE = RESET; r.B.TXEIE = SET; // po povolení přerušení okamžitě přeruší return r.R; }); return n; } void Usart::SetRS485 (const bool polarity) const { } void Usart::SetHalfDuplex (const bool on) const { } extern "C" { int terminate () { return 0; } };