128 lines
3.0 KiB
C
128 lines
3.0 KiB
C
/* Reflow Oven Controller
|
|
*
|
|
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
|
*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/**
|
|
* @file systick.c
|
|
*/
|
|
|
|
#include <reflow-controller/systick.h>
|
|
#include <helper-macros/helper-macros.h>
|
|
#include <stm32/stm32f4xx.h>
|
|
#include <cmsis/core_cm4.h>
|
|
|
|
volatile uint32_t IN_SECTION(.ccm.bss) wait_tick_ms = 0UL;
|
|
volatile uint64_t IN_SECTION(.ccm.bss) global_tick_ms = 0ULL;
|
|
volatile uint32_t IN_SECTION(.ccm.bss) lcd_tick_100us = 0UL;
|
|
|
|
void systick_setup(void)
|
|
{
|
|
/* Setup Systick for 100us tick @ 168 MHz Clock Speed */
|
|
SysTick_Config(SYSTICK_RELOAD);
|
|
}
|
|
|
|
void systick_wait_ms(uint32_t ms)
|
|
{
|
|
wait_tick_ms = 0UL;
|
|
while (wait_tick_ms < ms);
|
|
}
|
|
|
|
uint64_t systick_get_global_tick()
|
|
{
|
|
uint64_t temp;
|
|
|
|
__disable_irq();
|
|
temp = global_tick_ms;
|
|
__enable_irq();
|
|
|
|
return temp;
|
|
}
|
|
|
|
void systick_get_uptime_from_tick(uint32_t *days, uint32_t *hours, uint32_t *minutes, uint32_t *seconds)
|
|
{
|
|
uint64_t tick_secs;
|
|
uint32_t secs;
|
|
uint32_t mins;
|
|
uint32_t hs;
|
|
uint32_t ds;
|
|
|
|
|
|
tick_secs = systick_get_global_tick() / 1000;
|
|
secs = tick_secs % 60;
|
|
tick_secs /= 60;
|
|
mins = tick_secs % 60;
|
|
tick_secs /= 60;
|
|
hs = tick_secs % 60;
|
|
tick_secs /= 24;
|
|
ds = tick_secs;
|
|
|
|
if (days)
|
|
*days = ds;
|
|
if (hours)
|
|
*hours = hs;
|
|
if (minutes)
|
|
*minutes = mins;
|
|
if (seconds)
|
|
*seconds = secs;
|
|
|
|
}
|
|
|
|
bool __attribute__((optimize("O3"))) systick_ticks_have_passed(uint64_t start_timestamp, uint64_t ticks)
|
|
{
|
|
uint64_t end_timestamp = start_timestamp + ticks;
|
|
uint64_t current_timestamp = systick_get_global_tick();
|
|
|
|
/* wrap around expected */
|
|
if (end_timestamp < start_timestamp) {
|
|
/* Wrap around occured */
|
|
if (current_timestamp < start_timestamp) {
|
|
if (current_timestamp >= end_timestamp)
|
|
return true;
|
|
}
|
|
} else {
|
|
if (current_timestamp >= end_timestamp)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @brief Interrupt Handler for SysTick
|
|
*
|
|
* This handler is called every 100 us.
|
|
* It is important to keep this function simple as it is called that often and may prevent program flow.
|
|
*
|
|
* @warning For calling cyclic functions use separate timers/flags and don't spoil this function
|
|
*/
|
|
void __attribute__((optimize("O3"))) SysTick_Handler()
|
|
{
|
|
static uint32_t IN_SECTION(.ccm.bss) pre_tick = 0UL;
|
|
|
|
pre_tick++;
|
|
if (pre_tick == 10) {
|
|
pre_tick = 0;
|
|
/* Increase tick counters */
|
|
wait_tick_ms++;
|
|
global_tick_ms++;
|
|
}
|
|
|
|
lcd_tick_100us++;
|
|
}
|