From 5942d98e21aabd4e5ca40be850c0cf0ad6620ef1 Mon Sep 17 00:00:00 2001 From: Max Regan Date: Sat, 11 Apr 2020 11:08:50 -0700 Subject: [PATCH] Add UsartDriver (TX-only) --- firmware/Bsp/Drivers/UsartDriver.cpp | 95 ++++++++++++++++++++++++++++ firmware/Bsp/Drivers/UsartDriver.h | 47 ++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 firmware/Bsp/Drivers/UsartDriver.cpp create mode 100644 firmware/Bsp/Drivers/UsartDriver.h diff --git a/firmware/Bsp/Drivers/UsartDriver.cpp b/firmware/Bsp/Drivers/UsartDriver.cpp new file mode 100644 index 0000000..0c1b618 --- /dev/null +++ b/firmware/Bsp/Drivers/UsartDriver.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2019 Max Regan + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "Bsp/Drivers/UsartDriver.h" +#include "Bsp/macros.h" + +namespace BSP { + +using RC = BSP::ReturnCode; +using BSP::Schedule::TaskScheduler; +using BSP::Schedule::NextTime; +using BSP::Time; + +UsartDriver::UsartDriver(USART_TypeDef *usart, TaskScheduler &scheduler) + : m_scheduler(scheduler) + , m_usart(usart) +{} + +void UsartDriver::init() +{ + // TODO: This is all hardcoded for USART1 (doesn't exist on STM32L031) + +#if defined(STM32L0XX) + if (m_usart == USART2) { + RCC->APB1ENR |= RCC_APB1ENR_USART2EN; + } +#elif defined(STM32L4XX) + if (m_usart == USART1) { + RCC->APB2ENR |= RCC_APB2ENR_USART1EN; + } else if (m_usart == USART2) { + RCC->APB1ENR1 |= RCC_APB1ENR1_USART2EN; + } else if (m_usart == USART3) { + RCC->APB1ENR1 |= RCC_APB1ENR1_USART3EN; + } +#else +#error "Unknown device family" +#endif + + + // Set TX (PA9) to output, push/pull + SET_TO(GPIOA->AFR[1], GPIO_AFRH_AFSEL9, 7u << GPIO_AFRH_AFSEL9_Pos); //AF7 (USART1_TX) + SET_TO(GPIOA->MODER, GPIO_MODER_MODE9, 2u << GPIO_MODER_MODE9_Pos); // Alternate Function + GPIOA->OTYPER &= ~GPIO_OTYPER_OT_9; // push/pull + GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD9; // no pullup, no pulldown + + m_usart->BRR = (4100000) /115200L; // set baudrate (APBCLK / baud) + m_usart->CR1 |= (USART_CR1_RE | USART_CR1_TE); // RX, TX enable + m_usart->CR1 |= USART_CR1_UE; // USART enable +} + +NextTime UsartDriver::execute() +{ + return NextTime::never(); +} + +RC UsartDriver::tx_blocking(const uint8_t *data, size_t len) +{ + for (size_t i = 0; i < len; i++) { + while (!(m_usart->ISR & USART_ISR_TXE)) {} + m_usart->TDR = data[i]; + } + + return RC::OK; +} + +RC UsartDriver::tx_blocking(const char *data) +{ + size_t len = 0; + while (data[len] != '\0') { + len++; + }; + + return tx_blocking(reinterpret_cast(data), len); +} + + +} diff --git a/firmware/Bsp/Drivers/UsartDriver.h b/firmware/Bsp/Drivers/UsartDriver.h new file mode 100644 index 0000000..f7220b9 --- /dev/null +++ b/firmware/Bsp/Drivers/UsartDriver.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2019 Max Regan + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "Bsp/ReturnCode.h" +#include "Bsp/TaskScheduler.h" + +#include "Mcu.h" + +namespace BSP { + +class UsartDriver : public BSP::Schedule::Task { + +public: + // TODO: Add configurability / provide a real abstraction + UsartDriver(USART_TypeDef *usart, BSP::Schedule::TaskScheduler &scheduler); + + void init(); + BSP::Schedule::NextTime execute() override; + BSP::ReturnCode tx_blocking(const uint8_t *data, size_t len); + BSP::ReturnCode tx_blocking(const char *data); + +private: + BSP::Schedule::TaskScheduler &m_scheduler; + USART_TypeDef *m_usart; +}; + +}