33#include "arch/common/drivers/serial.h"
34#include "filesystem/file_access.h"
35#include "kernel/scheduler/scheduler.h"
65 asm volatile(
"bl _Z22usart1irqImplBoardcorev");
94 asm volatile(
"bl _Z22usart2irqImplBoardcorev");
123 asm volatile(
"bl _Z22usart3irqImplBoardcorev");
145 asm volatile(
"bl _Z21uart4irqImplBoardcorev");
167 asm volatile(
"bl _Z21uart5irqImplBoardcorev");
189 asm volatile(
"bl _Z22usart6irqImplBoardcorev");
211 asm volatile(
"bl _Z21uart7irqImplBoardcorev");
233 asm volatile(
"bl _Z21uart8irqImplBoardcorev");
242 : usart(usart), baudrate(baudrate)
245 switch (
reinterpret_cast<uint32_t
>(
usart))
305 D(assert(
false &&
"USART selected not supported!"));
314 bool received =
false;
317#ifndef _ARCH_CORTEXM7_STM32F7
319 received = ((
usart->SR & USART_SR_RXNE) == 0 ?
false :
true);
321 framingError = ((
usart->SR & USART_SR_FE) == 0 ?
false :
true);
322 idle = ((
usart->SR & USART_SR_IDLE) == 0 ?
false :
true);
327 received = ((
usart->ISR & USART_ISR_RXNE) == 0 ?
false :
true);
329 framingError = ((
usart->ISR & USART_ISR_FE) == 0 ?
false :
true);
330 idle = ((
usart->ISR & USART_ISR_IDLE) == 0 ?
false :
true);
332 usart->ICR = USART_ICR_IDLECF;
339 if (framingError || (received && !rxQueue.tryPut(c)))
344 if (error || idle || (rxQueue.size() >= rxQueue.capacity() / 2))
349 rxWaiter->IRQwakeup();
350 if (rxWaiter->IRQgetPriority() >
351 miosix::Thread::IRQgetCurrentThread()->IRQgetPriority())
353 miosix::Scheduler::IRQfindNextThread();
376 miosix::FastInterruptDisableLock dLock;
379 usart->CR1 |= USART_CR1_UE
386 usart->CR3 |= USART_CR3_ONEBIT;
390 ports[
id - 1] =
this;
393 NVIC_SetPriority(
irqn, 15);
394 NVIC_EnableIRQ(
irqn);
402 miosix::FastInterruptDisableLock dLock;
405 ports[this->
id - 1] =
nullptr;
408 usart->CR1 &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE);
411 NVIC_DisableIRQ(
irqn);
416 miosix::FastInterruptDisableLock dLock;
418 :
usart->CR1 |= USART_CR1_M);
419 this->wordLength = wordLength;
424 miosix::FastInterruptDisableLock dLock;
426 :
usart->CR1 |= USART_CR1_PCE);
427 this->parity = parity;
432 miosix::FastInterruptDisableLock dLock;
433 this->stopBits = stopBits;
434 usart->CR2 &= ~USART_CR2_STOP;
436 usart->CR2 |= USART_CR2_STOP_1;
441 miosix::FastInterruptDisableLock dLock;
442 this->over8 = oversampling;
443 (oversampling ?
usart->CR1 |= USART_CR1_OVER8
444 :
usart->CR1 &= ~USART_CR1_OVER8);
458 miosix::InterruptDisableLock dLock;
470 uint32_t brr = ((f << 2) / (((
int)
baudrate * (over8 ? 1 : 2))));
473 usart->BRR = (brr / 2) + (brr & 1);
478bool USART::readImpl(
void* buffer,
size_t nBytes,
size_t& nBytesRead,
479 const bool blocking, std::chrono::nanoseconds timeout)
481 miosix::Lock<miosix::FastMutex> l(rxMutex);
483 char* buf =
reinterpret_cast<char*
>(buffer);
487 bool timedOut =
false;
489 miosix::FastInterruptDisableLock dLock;
493 for (; result < nBytes; result++)
495 if (!rxQueue.tryGet(buf[result]))
499 miosix::FastInterruptEnableLock eLock(dLock);
505 if ((result == nBytes) || (idle && (!blocking || (result > 0))) ||
514 rxWaiter = miosix::Thread::IRQgetCurrentThread();
516 if (timeout == std::chrono::nanoseconds::zero())
518 miosix::Thread::IRQenableIrqAndWait(dLock);
522 int64_t wakeup =
add_sat(miosix::IRQgetTime(), timeout.count());
524 miosix::Thread::IRQenableIrqAndTimedWait(dLock, wakeup);
526 if (waitResult == miosix::TimedWaitResult::Timeout)
539 return (result > 0) && !timedOut;
544 miosix::Lock<miosix::FastMutex> l(txMutex);
548 const char* buf =
reinterpret_cast<const char*
>(buffer);
550 for (i = 0; i < nBytes; i++)
552#ifndef _ARCH_CORTEXM7_STM32F7
553 while ((
usart->SR & USART_SR_TXE) == 0)
557 while ((
usart->ISR & USART_ISR_TXE) == 0)
567 miosix::Lock<miosix::FastMutex> l(txMutex);
570#ifndef _ARCH_CORTEXM7_STM32F7
573 usart->TDR = *buffer;
578 while (*buffer !=
'\0')
582#ifndef _ARCH_CORTEXM7_STM32F7
583 while (!(
usart->SR & USART_SR_TXE))
587 while ((
usart->ISR & USART_ISR_TXE) == 0)
589 usart->TDR = *buffer;
598 std::ifstream file(fileName, std::ifstream::binary);
599 std::vector<uint8_t> buffer(1024, 0);
607 while (file.read(
reinterpret_cast<char*
>(buffer.data()), buffer.size()))
609 std::streamsize s = file.gcount();
611 write(buffer.data(),
static_cast<size_t>(s));
618 char buf[INTERNAL_QUEUE_LENGTH];
620 while (
read(buf, INTERNAL_QUEUE_LENGTH))
628 if (this->id < 1 || this->
id > 4)
630 LOG_ERR(
logger,
"USART selected not supported for STM32SerialWrapper!");
632 "USART selected not supported for STM32SerialWrapper!"));
636 this->serial =
new miosix::STM32Serial(
id,
baudrate);
638 if (!serialCommSetup())
641 "[STM32SerialWrapper] can't initialize serial communication!");
643 "[STM32SerialWrapper] Error : can't initialize serial "
644 "communication!\n"));
649 miosix::GpioPin tx, miosix::GpioPin rx)
652 if (this->id < 1 || this->
id > 4)
654 LOG_ERR(
logger,
"USART selected not supported for STM32SerialWrapper!");
656 "USART selected not supported for STM32SerialWrapper!"));
660 this->serial =
new miosix::STM32Serial(
id,
baudrate, tx, rx);
662 if (!serialCommSetup())
665 "[STM32SerialWrapper] can't initialize serial communication!");
667 "[STM32SerialWrapper] Error : can't initialize serial "
668 "communication!\n"));
674 miosix::intrusive_ref_ptr<miosix::DevFs> devFs =
675 miosix::FilesystemManager::instance().getDevFs();
680bool STM32SerialWrapper::serialCommSetup()
683 if (!miosix::FilesystemManager::instance().getDevFs()->addDevice(
685 miosix::intrusive_ref_ptr<miosix::Device>(serial)))
694 fd = open(serialPortPath.c_str(), O_RDWR);
698 TRACE(
"Cannot open %s\n", serialPortPath.c_str());
705bool STM32SerialWrapper::readImpl(
void* buffer,
size_t nBytes,
706 size_t& nBytesRead,
const bool blocking,
707 std::chrono::nanoseconds timeout)
713 "STM32SerialWrapper::read doesn't support non-blocking read");
715 "STM32SerialWrapper::read doesn't support non-blocking read"));
720 if (timeout != std::chrono::nanoseconds::zero())
723 "STM32SerialWrapper::read doesn't support timeout on read");
725 "STM32SerialWrapper::read doesn't support timeout on read"));
728 size_t n = ::read(fd, buffer, nBytes);
742 ::write(fd, buffer, strlen(buffer) + 1);
void __attribute__((naked)) CAN1_RX0_IRQHandler()
#define LOG_ERR(logger,...)
Boardcore::USART * ports[N_USART_PORTS]
< Pointer to serial port classes to let interrupts access the classes
void write(const void *buf, size_t nBytes)
Blocking write operation.
STM32SerialWrapper(USARTType *usart, int baudrate)
Initializes the serialPortName and initializes the default pins, which are:
~STM32SerialWrapper()
Removes the device from the list of the devices and closes the file of the device.
void writeString(const char *buffer)
Write a string to the serial, comprising the '\0' character.
Driver for STM32F4 low level USART/UART peripheral.
void setParity(ParityBit pb)
Set the presence of the parity in the data sent.
void IRQhandleInterrupt()
Interrupt handler that deals with receive and idle interrupts.
void setWordLength(WordLength wl)
Set the length of the word to 8 or to 9.
void writeString(const char *buffer)
Write a string to the serial, comprising the '\0' character.
void clearQueue()
Clears the rxQueue.
bool read(void *buffer, size_t nBytes)
Non-blocking read operation to read nBytes or till the data transfer is complete.
bool writeFile(const std::string &fileName)
Given a filename, uses the USART interface to stream the file in 1KB chunks.
USART(USARTType *usart, int baudrate, unsigned int queueLen=INTERNAL_QUEUE_LENGTH)
Automatically enables the peripheral and timer peripheral clock.
void write(const void *buf, size_t nBytes)
Blocking write operation.
void setStopBits(int stopBits)
Set the number of stop bits.
void setOversampling(bool oversampling)
Sets the Over8 bit.
void setBaudrate(int baudrate)
Set the baudrate in the BRR register.
~USART() override
Disables the flags for the generation of the interrupts, the IRQ from the NVIC, the peripheral and re...
Abstract class that implements the interface for the USART/UART serial communication.
USARTInterface(USARTType *usart, int baudrate)
Constructor of the USART in order to assign usart and baudrate.
IRQn_Type irqn
IRQ number.
virtual ~USARTInterface()=0
std::string serialPortName
bool enablePeripheralClock(void *peripheral)
Enables a peripheral clock source from the APB1 and APB2 peripheral buses.
uint32_t getAPBPeripheralsClock(APB bus)
Computes the output clock frequency for peripherals on the given APB.
This file includes all the types the logdecoder script will decode.
constexpr auto add_sat(T x, T y) noexcept -> typename std::enable_if_t< std::is_integral< T >::value, T >
Computes the saturating addition x + y for integral types.