/* Reflow Oven Controller * * Copyright (C) 2020 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 . */ /** * @file main.c * @brief Main file for firmware */ #include #include /* #include */ #include #include #include #include #include #include #include #include #include "fatfs/shimatta_sdio_driver/shimatta_sdio.h" #include #include #include #include #include #include #include #include static void setup_nvic_priorities() { /* No sub priorities */ NVIC_SetPriorityGrouping(2); /* Setup Priorities */ NVIC_SetPriority(ADC_IRQn, 2); NVIC_SetPriority(DMA2_Stream0_IRQn, 1); NVIC_SetPriority(DMA2_Stream7_IRQn, 3); } static float pt1000_value; static volatile int pt1000_value_status; static uint32_t rot; static volatile float pid_out; static volatile float current_temperature; FATFS fs; FATFS *fs_ptr = &fs; static inline void uart_gpio_config() { #ifdef DEBUGBUILD rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(SHELL_UART_PORT_RCC_MASK)); SHELL_UART_PORT->MODER &= MODER_DELETE(SHELL_UART_TX_PIN) & MODER_DELETE(SHELL_UART_RX_PIN); SHELL_UART_PORT->MODER |= ALTFUNC(SHELL_UART_RX_PIN) | ALTFUNC(SHELL_UART_TX_PIN); SETAF(SHELL_UART_PORT, SHELL_UART_RX_PIN, SHELL_UART_RX_PIN_ALTFUNC); SETAF(SHELL_UART_PORT, SHELL_UART_TX_PIN, SHELL_UART_TX_PIN_ALTFUNC); #endif } static char shell_uart_tx_buff[128]; static char shell_uart_rx_buff[32]; struct stm_uart shell_uart; static shellmatta_retCode_t write_shell_callback(const char *data, uint32_t len) { uart_send_array_with_dma(&shell_uart, data, len); return SHELLMATTA_OK; } static inline void setup_sell_uart(struct stm_uart *uart) { uart->rx = 1; uart->tx = 1; uart->brr_val = SHELL_UART_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); } static bool mount_sd_card_if_avail(bool mounted) { FRESULT res; if (sdio_check_inserted() && mounted) { memset(fs_ptr, 0, sizeof(FATFS)); return false; } if (!sdio_check_inserted() && !mounted) { res = f_mount(fs_ptr, "0:/", 1); if (res == FR_OK) { return true; } else { return false; } } return mounted; } const char *oven_controller_hello_world = "Hello world :)\n"; int main() { bool sd_card_mounted = false; FIL test_file; const char *uart_input; size_t uart_input_len; shellmatta_handle_t shell_handle; int uart_receive_status; static struct pid_controller pid; uint64_t pid_timestamp = 0; setup_nvic_priorities(); systick_setup(); adc_pt1000_setup_meas(); digio_setup_default_all(); led_setup(); loudspeaker_setup(); rotary_encoder_setup(); uart_gpio_config(); setup_sell_uart(&shell_uart); shell_handle = shell_init(write_shell_callback); shell_print_motd(shell_handle); if (f_mount(fs_ptr, "0:/", 1) == FR_OK) { sd_card_mounted = true; f_open(&test_file, "hello-world.txt", FA_OPEN_APPEND | FA_WRITE); f_write(&test_file, oven_controller_hello_world, strlen(oven_controller_hello_world), NULL); f_close(&test_file); } pid_init(&pid, 0.1, 0.1, 4.0, 0.0, 100.0, 40.0); pid_zero(&pid); while (1) { sd_card_mounted = mount_sd_card_if_avail(sd_card_mounted); pt1000_value_status = adc_pt1000_get_current_resistance(&pt1000_value); if (pt1000_value_status >= 0) { (void)temp_converter_convert_resistance_to_temp(pt1000_value, (float *)¤t_temperature); if ((systick_get_global_tick() - pid_timestamp) >= 250) { pid_out = pid_sample(&pid, 100.0 - current_temperature); pid_timestamp = systick_get_global_tick(); } } rot = rotary_encoder_get_abs_val(); uart_receive_status = uart_receive_data_with_dma(&shell_uart, &uart_input, &uart_input_len); if (uart_receive_status >= 1) shell_handle_input(shell_handle, uart_input, uart_input_len); } } void sdio_wait_ms(uint32_t ms) { systick_wait_ms(ms); } void DMA2_Stream7_IRQHandler() { uint32_t hisr = DMA2->HISR; DMA2->HIFCR = hisr; if (hisr & DMA_HISR_TCIF7) { uart_tx_dma_complete_int_callback(&shell_uart); } }