mirror of
https://fuchsia.googlesource.com/third_party/pigweed.googlesource.com/pigweed/pigweed
synced 2024-09-20 05:41:06 +00:00
eecf63ba84
Extends support for more hardware by supporting the following: - Uarts where tx and rx pins are on different ports. - Peripherals that are UARTs, not USARTs. Adds the following new config options which default to PW_SYS_IO_STM32CUBE_GPIO_PORT for backwards compatibility: - PW_SYS_IO_STM32CUBE_GPIO_TX_PORT - PW_SYS_IO_STM32CUBE_GPIO_RX_PORT Adds the following new config option which default to USART: - PW_SYS_IO_STM32CUBE_USART_PREFIX For example, this was useful with the following config on an STM32H7: PW_SYS_IO_STM32CUBE_GPIO_AF=8 PW_SYS_IO_STM32CUBE_USART_NUM=5 PW_SYS_IO_STM32CUBE_GPIO_TX_PORT=C PW_SYS_IO_STM32CUBE_GPIO_TX_PIN=12 PW_SYS_IO_STM32CUBE_GPIO_RX_PORT=D PW_SYS_IO_STM32CUBE_GPIO_RX_PIN=2 PW_SYS_IO_STM32CUBE_USART_PREFIX=UART Change-Id: I9cbd2742dd2fc3ff031874f18dc80241e6c7675d Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/105540 Reviewed-by: Armando Montanez <amontanez@google.com> Pigweed-Auto-Submit: Armando Montanez <amontanez@google.com> Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
135 lines
4.7 KiB
C++
135 lines
4.7 KiB
C++
// Copyright 2021 The Pigweed Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
// use this file except in compliance with the License. You may obtain a copy of
|
|
// the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
// License for the specific language governing permissions and limitations under
|
|
// the License.
|
|
|
|
#include "pw_sys_io/sys_io.h"
|
|
|
|
#include <cinttypes>
|
|
|
|
#include "pw_preprocessor/concat.h"
|
|
#include "pw_status/status.h"
|
|
#include "pw_sys_io_stm32cube_private/config.h"
|
|
#include "stm32cube/stm32cube.h"
|
|
|
|
// These macros remap config options to the various STM32Cube HAL macro names.
|
|
|
|
// USART_INSTANCE defined to USARTn, where n is the USART peripheral index.
|
|
#define USART_INSTANCE \
|
|
PW_CONCAT(PW_SYS_IO_STM32CUBE_USART_PREFIX, PW_SYS_IO_STM32CUBE_USART_NUM)
|
|
|
|
// USART_GPIO_ALTERNATE_FUNC defined to GPIO_AFm_USARTn, where m is the
|
|
// alternate function index and n is the USART peripheral index.
|
|
#define USART_GPIO_ALTERNATE_FUNC \
|
|
PW_CONCAT(GPIO_AF, \
|
|
PW_SYS_IO_STM32CUBE_GPIO_AF, \
|
|
_, \
|
|
PW_SYS_IO_STM32CUBE_USART_PREFIX, \
|
|
PW_SYS_IO_STM32CUBE_USART_NUM)
|
|
|
|
// USART_GPIO_PORT defined to GPIOx, where x is the GPIO port letter that the
|
|
// TX/RX pins are on.
|
|
#define USART_GPIO_TX_PORT PW_CONCAT(GPIO, PW_SYS_IO_STM32CUBE_GPIO_TX_PORT)
|
|
#define USART_GPIO_RX_PORT PW_CONCAT(GPIO, PW_SYS_IO_STM32CUBE_GPIO_RX_PORT)
|
|
#define USART_GPIO_TX_PIN PW_CONCAT(GPIO_PIN_, PW_SYS_IO_STM32CUBE_GPIO_TX_PIN)
|
|
#define USART_GPIO_RX_PIN PW_CONCAT(GPIO_PIN_, PW_SYS_IO_STM32CUBE_GPIO_RX_PIN)
|
|
|
|
// USART_GPIO_PORT_ENABLE defined to __HAL_RCC_GPIOx_CLK_ENABLE, where x is the
|
|
// GPIO port letter that the TX/RX pins are on.
|
|
#define USART_GPIO_TX_PORT_ENABLE \
|
|
PW_CONCAT(__HAL_RCC_GPIO, PW_SYS_IO_STM32CUBE_GPIO_TX_PORT, _CLK_ENABLE)
|
|
|
|
#define USART_GPIO_RX_PORT_ENABLE \
|
|
PW_CONCAT(__HAL_RCC_GPIO, PW_SYS_IO_STM32CUBE_GPIO_RX_PORT, _CLK_ENABLE)
|
|
|
|
// USART_ENABLE defined to __HAL_RCC_USARTn_CLK_ENABLE, where n is the USART
|
|
// peripheral index.
|
|
#define USART_ENABLE \
|
|
PW_CONCAT(__HAL_RCC_, \
|
|
PW_SYS_IO_STM32CUBE_USART_PREFIX, \
|
|
PW_SYS_IO_STM32CUBE_USART_NUM, \
|
|
_CLK_ENABLE)
|
|
|
|
static UART_HandleTypeDef uart;
|
|
|
|
extern "C" void pw_sys_io_Init() {
|
|
GPIO_InitTypeDef GPIO_InitStruct = {};
|
|
|
|
USART_ENABLE();
|
|
USART_GPIO_TX_PORT_ENABLE();
|
|
USART_GPIO_RX_PORT_ENABLE();
|
|
|
|
GPIO_InitStruct.Pin = USART_GPIO_TX_PIN;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
|
GPIO_InitStruct.Alternate = USART_GPIO_ALTERNATE_FUNC;
|
|
HAL_GPIO_Init(USART_GPIO_TX_PORT, &GPIO_InitStruct);
|
|
|
|
GPIO_InitStruct.Pin = USART_GPIO_RX_PIN;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
|
GPIO_InitStruct.Alternate = USART_GPIO_ALTERNATE_FUNC;
|
|
HAL_GPIO_Init(USART_GPIO_RX_PORT, &GPIO_InitStruct);
|
|
|
|
uart.Instance = USART_INSTANCE;
|
|
uart.Init.BaudRate = 115200;
|
|
uart.Init.WordLength = UART_WORDLENGTH_8B;
|
|
uart.Init.StopBits = UART_STOPBITS_1;
|
|
uart.Init.Parity = UART_PARITY_NONE;
|
|
uart.Init.Mode = UART_MODE_TX_RX;
|
|
uart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
|
uart.Init.OverSampling = UART_OVERSAMPLING_16;
|
|
HAL_UART_Init(&uart);
|
|
}
|
|
|
|
// This whole implementation is very inefficient because it uses the synchronous
|
|
// polling UART API and only reads / writes 1 byte at a time.
|
|
namespace pw::sys_io {
|
|
Status ReadByte(std::byte* dest) {
|
|
if (HAL_UART_Receive(
|
|
&uart, reinterpret_cast<uint8_t*>(dest), 1, HAL_MAX_DELAY) !=
|
|
HAL_OK) {
|
|
return Status::ResourceExhausted();
|
|
}
|
|
return OkStatus();
|
|
}
|
|
|
|
Status TryReadByte(std::byte* dest) { return Status::Unimplemented(); }
|
|
|
|
Status WriteByte(std::byte b) {
|
|
if (HAL_UART_Transmit(
|
|
&uart, reinterpret_cast<uint8_t*>(&b), 1, HAL_MAX_DELAY) != HAL_OK) {
|
|
return Status::ResourceExhausted();
|
|
}
|
|
return OkStatus();
|
|
}
|
|
|
|
// Writes a string using pw::sys_io, and add newline characters at the end.
|
|
StatusWithSize WriteLine(const std::string_view& s) {
|
|
size_t chars_written = 0;
|
|
StatusWithSize result = WriteBytes(as_bytes(span(s)));
|
|
if (!result.ok()) {
|
|
return result;
|
|
}
|
|
chars_written += result.size();
|
|
|
|
// Write trailing newline.
|
|
result = WriteBytes(as_bytes(span("\r\n", 2)));
|
|
chars_written += result.size();
|
|
|
|
return StatusWithSize(OkStatus(), chars_written);
|
|
}
|
|
|
|
} // namespace pw::sys_io
|