/* Reflow Oven Controller * * Copyright (C) 2021 Mario Hüttel * * This file is part of the Reflow Oven Controller Project. * * The reflow oven controller is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * The Reflow Oven Control Firmware is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the reflow oven controller project. * If not, see . */ #include #include #include #include #include /** * @brief TX buffer for the shell's uart */ static char shell_uart_tx_buff[4096]; /** * @brief RX buffer for the shell's uart */ static char shell_uart_rx_buff[128]; /** * @brief The uart instance handling the shellmatta shell. */ struct stm_uart shell_uart; void shell_uart_setup(void) { struct stm_uart *uart = &shell_uart; uart->rx = 1; uart->tx = 1; uart->brr_val = SHELL_UART_DEFAULT_BRR_REG_VALUE; uart->rcc_reg = &SHELL_UART_RCC_REG; uart->rcc_bit_no = BITMASK_TO_BITNO(SHELL_UART_RCC_MASK); uart->uart_dev = SHELL_UART_PERIPH; uart->dma_rx_buff = shell_uart_rx_buff; uart->dma_tx_buff = shell_uart_tx_buff; uart->rx_buff_count = sizeof(shell_uart_rx_buff); uart->tx_buff_count = sizeof(shell_uart_tx_buff); uart->base_dma_num = 2; uart->dma_rx_stream = SHELL_UART_RECEIVE_DMA_STREAM; uart->dma_tx_stream = SHELL_UART_SEND_DMA_STREAM; uart->dma_rx_trigger_channel = SHELL_UART_RX_DMA_TRIGGER; uart->dma_tx_trigger_channel = SHELL_UART_TX_DMA_TRIGGER; uart_init(uart); NVIC_EnableIRQ(DMA2_Stream7_IRQn); } shellmatta_retCode_t shell_uart_write_callback(const char *data, uint32_t len) { uart_send_array_with_dma(&shell_uart, data, len); return SHELLMATTA_OK; } int shell_uart_receive_data_with_dma(const char **data, size_t *len) { return uart_receive_data_with_dma(&shell_uart, data, len); } int32_t shell_uart_reconfig_baud(uint32_t new_baud) { uint32_t brr_val_floor; uint32_t brr_val_remainder; uint32_t error_permille; int64_t actual_baud; /* Calculate the new BRR register value */ brr_val_floor = SHELL_UART_PERIPHERAL_CLOCK / new_baud; brr_val_remainder = SHELL_UART_PERIPHERAL_CLOCK % new_baud; /* Round to the nearest value */ if (brr_val_remainder > (new_baud / 2u)) { brr_val_floor++; brr_val_remainder = new_baud - brr_val_remainder; } actual_baud = (1000U *(int64_t)SHELL_UART_PERIPHERAL_CLOCK) / brr_val_floor; error_permille = (ABS(actual_baud - 1000U * (int64_t)new_baud)) / (int64_t)new_baud; if (error_permille < 20u) { uart_change_brr(&shell_uart, brr_val_floor); } else { return -1; } return (int32_t)error_permille; } uint32_t shell_uart_get_current_baudrate(void) { uint32_t brr; brr = uart_get_brr(&shell_uart); if (brr == 0) return 0; return (SHELL_UART_PERIPHERAL_CLOCK) / brr; } /** * @brief Handles the TX of UART1 (Shellmatta) */ void DMA2_Stream7_IRQHandler(void) { uint32_t hisr = DMA2->HISR & (0x3F << 22); DMA2->HIFCR = hisr; if (hisr & DMA_HISR_TCIF7) uart_tx_dma_complete_int_callback(&shell_uart); }