diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2019-07-23 23:51:31 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2019-07-25 18:08:28 -0400 |
commit | d501ca6b0b8d58d666cfbee87731e409b55dd902 (patch) | |
tree | 1ec67bf43d27fd64e7e8c801cb07961eadc6ee4a /src/stm32f4/serial.c | |
parent | 5a02572001d1d903bdb36c13396efe73f3835a67 (diff) | |
download | kutter-d501ca6b0b8d58d666cfbee87731e409b55dd902.tar.gz kutter-d501ca6b0b8d58d666cfbee87731e409b55dd902.tar.xz kutter-d501ca6b0b8d58d666cfbee87731e409b55dd902.zip |
stm32f4: Add initial support for STM32F446 chip
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src/stm32f4/serial.c')
-rw-r--r-- | src/stm32f4/serial.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/stm32f4/serial.c b/src/stm32f4/serial.c new file mode 100644 index 00000000..951a8297 --- /dev/null +++ b/src/stm32f4/serial.c @@ -0,0 +1,55 @@ +// STM32F4 serial +// +// Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net> +// +// This file may be distributed under the terms of the GNU GPLv3 license. + +#include "autoconf.h" // CONFIG_SERIAL_BAUD +#include "board/serial_irq.h" // serial_rx_byte +#include "command.h" // DECL_CONSTANT_STR +#include "internal.h" // enable_pclock +#include "sched.h" // DECL_INIT + +DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA3,PA2"); + +#define CR1_FLAGS (USART_CR1_UE | USART_CR1_RE | USART_CR1_TE \ + | USART_CR1_RXNEIE) + +void +serial_init(void) +{ + enable_pclock(USART2_BASE); + + uint32_t pclk = get_pclock_frequency(USART2_BASE); + uint32_t div = pclk / (CONFIG_SERIAL_BAUD * 16); + USART2->BRR = div << USART_BRR_DIV_Mantissa_Pos; + USART2->CR1 = CR1_FLAGS; + NVIC_SetPriority(USART2_IRQn, 0); + NVIC_EnableIRQ(USART2_IRQn); + + gpio_peripheral(GPIO('A', 2), GPIO_FUNCTION, 7, 0); + gpio_peripheral(GPIO('A', 3), GPIO_FUNCTION, 7, 1); +} +DECL_INIT(serial_init); + +void __visible +USART2_IRQHandler(void) +{ + uint32_t sr = USART2->SR; + if (sr & (USART_SR_RXNE | USART_SR_ORE)) + serial_rx_byte(USART2->DR); + if (sr & USART_SR_TXE && USART2->CR1 & USART_CR1_TXEIE) { + uint8_t data; + int ret = serial_get_tx_byte(&data); + if (ret) + USART2->CR1 = CR1_FLAGS; + else + USART2->DR = data; + } +} + +void +serial_enable_tx_irq(void) +{ + USART2->CR1 = CR1_FLAGS | USART_CR1_TXEIE; +} |