Compare commits
21 Commits
fd2994f9b9
...
temp-profi
Author | SHA1 | Date | |
---|---|---|---|
b5c002da5e | |||
fdc5bcdae3 | |||
c3dd6248a3 | |||
6ca38419ad | |||
5c429ec894 | |||
62ef147105 | |||
0e5ef46512 | |||
b83f057e49 | |||
fc2744d7fa | |||
223de7f190 | |||
dc6e973d52 | |||
5b4dc705b4 | |||
5190e3116b | |||
06893c21ab | |||
c6038969ca | |||
0c8a0cd562 | |||
1300fe88a4 | |||
df593e2ab2 | |||
34ad930bd8 | |||
1c1874abf1 | |||
43b14bdb92 |
@@ -114,7 +114,7 @@ add_executable(${ELFFILE} ${MAIN_SOURCES} ${CFG_PARSER_SRCS} ${UI_SRCS}
|
||||
${STM_PERIPH_SRCS} ${SETTINGS_SRCS} ${SAFETY_SRCS}
|
||||
${SHELLMATTA_SRCS} ${UPDATER_SRCS} ${PROFILE_SRCS}
|
||||
)
|
||||
|
||||
|
||||
add_dependencies(${ELFFILE} updater-ram-code-header-blob generate-version-header)
|
||||
|
||||
|
||||
|
Submodule stm-firmware/base64-lib updated: 251e90abf3...0418c0702d
@@ -126,7 +126,15 @@ enum analog_value_monitor {
|
||||
#define WATCHDOG_HALT_DEBUG (0)
|
||||
#endif
|
||||
|
||||
#define WATCHDOG_PRESCALER 16
|
||||
/**
|
||||
* @brief Watchdog clock prescaler value
|
||||
*/
|
||||
#define WATCHDOG_PRESCALER (16)
|
||||
|
||||
/**
|
||||
* @brief Watchdog reload value
|
||||
*/
|
||||
#define WATCHDOG_RELOAD_VALUE (2500)
|
||||
|
||||
/**
|
||||
* @brief Minimum number of bytes that have to be free on the stack. If this is not the case, an error is detected
|
||||
@@ -228,6 +236,6 @@ enum analog_value_monitor {
|
||||
ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_FLASH_CRC_DATA, SAFETY_FLAG_CONFIG_WEIGHT_PANIC), \
|
||||
ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_CFG_CRC_MEAS_ADC, SAFETY_FLAG_CONFIG_WEIGHT_PID), \
|
||||
ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_CFG_CRC_SAFETY_ADC, SAFETY_FLAG_CONFIG_WEIGHT_PANIC), \
|
||||
ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_CFG_CRC_MISC, SAFETY_FLAG_CONFIG_WEIGHT_NONE)
|
||||
ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_CFG_CRC_MISC, SAFETY_FLAG_CONFIG_WEIGHT_PANIC)
|
||||
|
||||
#endif /* __SAFETY_CONFIG_H__ */
|
||||
|
@@ -27,11 +27,19 @@
|
||||
|
||||
/**
|
||||
* @brief Setup the watchdog for the safety controller
|
||||
* @param Prescaler to use for the 32 KHz LSI clock
|
||||
*
|
||||
* The watchdog timeout can be calculated with:
|
||||
* \f[ t = \frac{(\mathrm{RELOAD_VAL} + 1)\cdot \mathrm{PRESCALER}}{32000 } s\f]
|
||||
*
|
||||
* Valid prescaler values are: 4, 8, 16, 32, 64, 128, 256.
|
||||
* @param prescaler Prescaler to use for the 32 KHz LSI clock
|
||||
* @param reload_value Reload value to reload the timer with when reset. 0 to 0xFFF
|
||||
* @return 0 if successful
|
||||
* @return -1 if prescaler is wrong
|
||||
* @return -2 if a reload value > 0xFFF is selected. 0xFFF will be used in this case
|
||||
* @note Once the watchdog is enabled, it cannot be turned off!
|
||||
*/
|
||||
int watchdog_setup(uint8_t prescaler);
|
||||
int watchdog_setup(uint16_t prescaler, uint16_t reload_value);
|
||||
|
||||
/**
|
||||
* @brief Reset watchdog counter
|
||||
|
Submodule stm-firmware/linklist-lib updated: 18b3ab377a...fdd99bad48
@@ -322,6 +322,7 @@ static const struct crc_monitor_register safety_adc_crc_regs[] = {
|
||||
static const struct crc_monitor_register misc_config_crc_regs[] = {
|
||||
/* Check clock tree settings */
|
||||
CRC_MON_REGISTER_ENTRY(RCC->CR, RCC_CR_PLLON | RCC_CR_HSEON | RCC_CR_PLLI2SON | RCC_CR_HSION, 4),
|
||||
CRC_MON_REGISTER_ENTRY(RCC->CSR, RCC_CSR_LSION, 4),
|
||||
CRC_MON_REGISTER_ENTRY(RCC->CFGR, RCC_CFGR_SWS | RCC_CFGR_HPRE | RCC_CFGR_PPRE1 | RCC_CFGR_PPRE2, 4),
|
||||
CRC_MON_REGISTER_ENTRY(RCC->PLLCFGR, RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLQ | RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLP | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLM , 4),
|
||||
/* Check Flash settings */
|
||||
@@ -329,7 +330,7 @@ static const struct crc_monitor_register misc_config_crc_regs[] = {
|
||||
/* Check vector table offset */
|
||||
CRC_MON_REGISTER_ENTRY(SCB->VTOR, 0xFFFFFFFF, 4),
|
||||
/* Check system tick configuration */
|
||||
CRC_MON_REGISTER_ENTRY(SysTick->CTRL, 0xFFFFFFFF, 4),
|
||||
CRC_MON_REGISTER_ENTRY(SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk, 4),
|
||||
CRC_MON_REGISTER_ENTRY(SysTick->LOAD, 0xFFFFFFFF, 4),
|
||||
CRC_MON_REGISTER_SENTINEL
|
||||
};
|
||||
@@ -972,7 +973,7 @@ void safety_controller_init(void)
|
||||
MEAS_ADC_SAFETY_FLAG_KEY);
|
||||
|
||||
safety_adc_init();
|
||||
watchdog_setup(WATCHDOG_PRESCALER);
|
||||
(void)watchdog_setup(WATCHDOG_PRESCALER, WATCHDOG_RELOAD_VALUE);
|
||||
|
||||
if (rcc_manager_get_reset_cause(false) & RCC_RESET_SOURCE_IWDG)
|
||||
safety_controller_report_error(ERR_FLAG_WTCHDG_FIRED);
|
||||
|
@@ -42,9 +42,10 @@
|
||||
*/
|
||||
#define STM32_WATCHDOG_REGISTER_ACCESS_KEY 0x5555
|
||||
|
||||
int watchdog_setup(uint8_t prescaler)
|
||||
int watchdog_setup(uint16_t prescaler, uint16_t reload_value)
|
||||
{
|
||||
uint32_t prescaler_reg_val;
|
||||
int ret = 0;
|
||||
|
||||
/** - Activate the LSI oscillator */
|
||||
RCC->CSR |= RCC_CSR_LSION;
|
||||
@@ -53,20 +54,24 @@ int watchdog_setup(uint8_t prescaler)
|
||||
while (!(RCC->CSR & RCC_CSR_LSIRDY))
|
||||
;
|
||||
|
||||
if (prescaler == 4U)
|
||||
if (prescaler == 4U) {
|
||||
prescaler_reg_val = 0UL;
|
||||
else if (prescaler == 8U)
|
||||
} else if (prescaler == 8U) {
|
||||
prescaler_reg_val = 1UL;
|
||||
else if (prescaler == 16U)
|
||||
} else if (prescaler == 16U) {
|
||||
prescaler_reg_val = 2UL;
|
||||
else if (prescaler == 32U)
|
||||
} else if (prescaler == 32U) {
|
||||
prescaler_reg_val = 3UL;
|
||||
else if (prescaler == 64U)
|
||||
} else if (prescaler == 64U) {
|
||||
prescaler_reg_val = 4UL;
|
||||
else if (prescaler == 128U)
|
||||
} else if (prescaler == 128U) {
|
||||
prescaler_reg_val = 5UL;
|
||||
else
|
||||
} else if (prescaler == 256U) {
|
||||
prescaler_reg_val = 6UL;
|
||||
} else {
|
||||
prescaler_reg_val = 6UL;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/** - (De)activate the watchdog during debug access according to @ref WATCHDOG_HALT_DEBUG */
|
||||
if (WATCHDOG_HALT_DEBUG)
|
||||
@@ -88,8 +93,12 @@ int watchdog_setup(uint8_t prescaler)
|
||||
while (IWDG->SR & IWDG_SR_RVU)
|
||||
;
|
||||
|
||||
/** - Set reload value fixed to 0xFFF */
|
||||
IWDG->RLR = 0xFFFU;
|
||||
/** - Set reload value */
|
||||
if (reload_value > 0xFFFu) {
|
||||
reload_value = 0xFFFFu;
|
||||
ret = -2;
|
||||
}
|
||||
IWDG->RLR = reload_value;
|
||||
|
||||
/** - Write enable key */
|
||||
IWDG->KR = STM32_WATCHDOG_ENABLE_KEY;
|
||||
@@ -97,7 +106,7 @@ int watchdog_setup(uint8_t prescaler)
|
||||
/** - Do a first reset of the counter. This also locks the config regs */
|
||||
watchdog_ack(WATCHDOG_MAGIC_KEY);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int watchdog_ack(uint32_t magic)
|
||||
|
@@ -2,7 +2,7 @@ project(updater-ram-code)
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
set(CMAKE_CROSSCOMPILING 1)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
set(CMAKE_TOOLCHAIN_FILE "arm-none-eabi-gcc.cmake")
|
||||
|
||||
|
@@ -1,35 +1,45 @@
|
||||
#!env python
|
||||
|
||||
# Convert a file to a c array
|
||||
# bin2carray <output file> <input file>
|
||||
"""
|
||||
Convert a file to a c array
|
||||
bin2carray <output file> <input file>
|
||||
"""
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
sys.exit(-1)
|
||||
def main():
|
||||
"""
|
||||
Main script function
|
||||
"""
|
||||
if len(sys.argv) < 3:
|
||||
return -1
|
||||
|
||||
source_file = sys.argv[2]
|
||||
dest_file = sys.argv[1]
|
||||
source_file = sys.argv[2]
|
||||
dest_file = sys.argv[1]
|
||||
|
||||
print("%s --> %s" % (source_file, dest_file))
|
||||
print(f'{source_file} --> {dest_file}')
|
||||
|
||||
with open(source_file, "rb") as src:
|
||||
data = src.read()
|
||||
with open(source_file, 'rb') as src:
|
||||
data = src.read()
|
||||
|
||||
with open(dest_file, "w") as dest:
|
||||
header_guard = "__" + os.path.basename(dest_file).replace('.', '_').replace('-', '_') + "_H__"
|
||||
dest.write("#ifndef %s\n" % (header_guard))
|
||||
dest.write("#define %s\n" % (header_guard))
|
||||
dest.write("static const char binary_blob[%d] = {\n" % (len(data)))
|
||||
for current,idx in zip(data, range(len(data))):
|
||||
if ((idx+1) % 4 == 0):
|
||||
dest.write(hex(current)+",\n")
|
||||
else:
|
||||
dest.write(hex(current)+",")
|
||||
with open(dest_file, 'w', encoding='utf-8') as dest:
|
||||
header_guard = '_' + os.path.basename(dest_file).replace('.', '_').replace('-', '_') + '_H_'
|
||||
header_guard = header_guard.upper()
|
||||
dest.write(f'#ifndef {header_guard}\n')
|
||||
dest.write(f'#define {header_guard}\n')
|
||||
dest.write(f'static const char binary_blob[{len(data)}] = {{\n')
|
||||
for idx, current in enumerate(data, start=1):
|
||||
if idx % 4 == 0:
|
||||
dest.write(hex(current)+',\n')
|
||||
else:
|
||||
dest.write(hex(current)+',')
|
||||
|
||||
dest.write("};\n")
|
||||
dest.write("#endif /* %s */\n" % (header_guard))
|
||||
dest.write('};\n')
|
||||
dest.write(f'#endif /* {header_guard} */\n')
|
||||
|
||||
sys.exit(0)
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
|
3
tprcc/.gitignore
vendored
Normal file
3
tprcc/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*.o
|
||||
build/*
|
||||
.cache/*
|
46
tprcc/CMakeLists.txt
Normal file
46
tprcc/CMakeLists.txt
Normal file
@@ -0,0 +1,46 @@
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
project(tprcc LANGUAGES CXX)
|
||||
|
||||
set (CMAKE_CXX_STANDARD 17)
|
||||
add_compile_options(-Wall -Wextra)
|
||||
|
||||
aux_source_directory("src" SRC_DIR)
|
||||
aux_source_directory("src/tpr" SRC_TPR_DIR)
|
||||
|
||||
set(TPR_PARSER_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated-tpr")
|
||||
|
||||
set (SRC_GENERATED "${TPR_PARSER_DIR}/tpr-parser.cpp" "${TPR_PARSER_DIR}/tpr-scanner.cpp")
|
||||
|
||||
set (SOURCES
|
||||
${SRC_DIR}
|
||||
${SRC_TPR_DIR}
|
||||
${SRC_GENERATED}
|
||||
)
|
||||
|
||||
|
||||
add_custom_command(
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/parser/tpr.l
|
||||
OUTPUT
|
||||
${TPR_PARSER_DIR}/tpr-scanner.cpp
|
||||
COMMAND
|
||||
mkdir -p "${TPR_PARSER_DIR}" && flex -+ -o "${TPR_PARSER_DIR}/tpr-scanner.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/parser/tpr.l"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/parser/tpr.ypp
|
||||
OUTPUT
|
||||
${TPR_PARSER_DIR}/tpr-parser.cpp
|
||||
COMMAND
|
||||
mkdir -p "${TPR_PARSER_DIR}/include/tpr-parser" && ${CMAKE_CURRENT_SOURCE_DIR}/bison-wrapper.sh "${TPR_PARSER_DIR}/tpr-parser.cpp" "${TPR_PARSER_DIR}/include/tpr-parser/tpr-parser.hpp" "${TPR_PARSER_DIR}/include/tpr-parser/location.hh" --header=tpr-parser.hpp ${CMAKE_CURRENT_SOURCE_DIR}/parser/tpr.ypp
|
||||
)
|
||||
|
||||
SET_SOURCE_FILES_PROPERTIES(${SRC_GENERATED} PROPERTIES GENERATED 1)
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE "${TPR_PARSER_DIR}/include" "${TPR_PARSER_DIR}/include/tpr-parser")
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
# TEMPORARY FIx:
|
||||
#target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
31
tprcc/bison-wrapper.sh
Executable file
31
tprcc/bison-wrapper.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Usage: bison-wrapper.sh <c-file> <include-file> <location.hh> <bison_file> <bison-parameters>
|
||||
if [[ $# -lt 4 ]]; then
|
||||
echo "Error. Not enough parameters"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
cfile=$1
|
||||
shift
|
||||
include=$1
|
||||
shift
|
||||
location=$1
|
||||
shift
|
||||
|
||||
tmpdir=`mktemp -d`
|
||||
cd $tmpdir
|
||||
echo "Using $tmpdir"
|
||||
echo cp *.tab.cpp "$cfile"
|
||||
echo cp *.hpp "$include"
|
||||
echo cp location.hh "$location"
|
||||
|
||||
bison $@
|
||||
cp *.tab.cpp "$cfile"
|
||||
cp *.hpp "$include"
|
||||
cp location.hh "$location"
|
||||
|
||||
|
||||
rm -rfv "$tmpdir"
|
31
tprcc/include/lang/temp-lang-frontend.hpp
Normal file
31
tprcc/include/lang/temp-lang-frontend.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef _TEMP_LANG_FRONTEND_HPP_
|
||||
#define _TEMP_LANG_FRONTEND_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <istream>
|
||||
#include <streambuf>
|
||||
|
||||
class TempLangFrontend {
|
||||
public:
|
||||
TempLangFrontend(const std::string &source_file)
|
||||
{
|
||||
m_source_file = source_file;
|
||||
}
|
||||
|
||||
virtual int analyze() = 0;
|
||||
|
||||
const std::string &get_src_file()
|
||||
{
|
||||
return m_source_file;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string m_source_file;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* _TEMP_LANG_FRONTEND_HPP_ */
|
20
tprcc/include/tpr/tpr-frontend.hpp
Normal file
20
tprcc/include/tpr/tpr-frontend.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef _TPR_FRONTEND_HPP_
|
||||
#define _TPR_FRONTEND_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <lang/temp-lang-frontend.hpp>
|
||||
#include <tpr/tpr-scanner.hpp>
|
||||
|
||||
namespace tpr {
|
||||
|
||||
class TprFrontend : public TempLangFrontend {
|
||||
private:
|
||||
public:
|
||||
TprFrontend(const std::string &source_file);
|
||||
int analyze() override;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _TPR_FRONTEND_HPP_ */
|
38
tprcc/include/tpr/tpr-scanner.hpp
Normal file
38
tprcc/include/tpr/tpr-scanner.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef _TPR_SCANNER_HPP_
|
||||
#define _TPR_SCANNER_HPP_
|
||||
|
||||
|
||||
#if ! defined(yyFlexLexerOnce)
|
||||
#include <FlexLexer.h>
|
||||
#endif
|
||||
|
||||
#include <tpr-parser/tpr-parser.hpp>
|
||||
#include <tpr-parser/location.hh>
|
||||
|
||||
namespace tpr {
|
||||
|
||||
class TempProfileScanner : public yyFlexLexer{
|
||||
public:
|
||||
|
||||
TempProfileScanner(std::istream *in) : yyFlexLexer(in) {
|
||||
};
|
||||
virtual ~TempProfileScanner() {};
|
||||
|
||||
//get rid of override virtual function warning
|
||||
using FlexLexer::yylex;
|
||||
|
||||
virtual
|
||||
int yylex( tpr::TempProfileParser::semantic_type * const lval,
|
||||
tpr::TempProfileParser::location_type *loc );
|
||||
// YY_DECL defined in mc_lexer.l
|
||||
// Method body created by flex in mc_lexer.yy.cc
|
||||
|
||||
private:
|
||||
/* yyval ptr */
|
||||
tpr::TempProfileParser::semantic_type *yylval = nullptr;
|
||||
};
|
||||
|
||||
} /* end namespace MC */
|
||||
|
||||
|
||||
#endif /* _TPR_SCANNER_HPP_ */
|
38
tprcc/include/tpr/tpr-types.hpp
Normal file
38
tprcc/include/tpr/tpr-types.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef _TPR_TYPES_HPP_
|
||||
#define _TPR_TYPES_HPP_
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace tpr {
|
||||
|
||||
enum class CommandType {
|
||||
pid_conf,
|
||||
temp_set,
|
||||
wait_temp,
|
||||
wait_time,
|
||||
temp_ramp,
|
||||
beep,
|
||||
temp_off,
|
||||
clear_flags,
|
||||
digio_conf,
|
||||
digio_set,
|
||||
digio_wait,
|
||||
};
|
||||
|
||||
|
||||
class TprCommand {
|
||||
private:
|
||||
CommandType m_type;
|
||||
std::vector<float> m_parameters;
|
||||
|
||||
public:
|
||||
TprCommand(CommandType type);
|
||||
TprCommand(CommandType type, const std::vector<float> ¶ms);
|
||||
TprCommand(CommandType type, const std::vector<float> &¶ms);
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* _TPR_TYPES_HPP_ */
|
31
tprcc/include/tprcc/logger.hpp
Normal file
31
tprcc/include/tprcc/logger.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef _LOGGER_HPP_
|
||||
#define _LOGGER_HPP_
|
||||
|
||||
#include <string>
|
||||
|
||||
enum class LogLevel {
|
||||
DEBUG,
|
||||
INFO,
|
||||
WARNING,
|
||||
ERROR,
|
||||
};
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
Logger(Logger &other) = delete;
|
||||
void operator=(const Logger &) = delete;
|
||||
|
||||
void log(LogLevel lvl, const std::string &message) const;
|
||||
|
||||
static Logger *get_logger();
|
||||
|
||||
protected:
|
||||
/* Create a proteceted instructure, to prevent construction outside of this class */
|
||||
Logger();
|
||||
|
||||
static Logger *logger_inst;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* _LOGGER_HPP_ */
|
54
tprcc/parser/tpr.l
Normal file
54
tprcc/parser/tpr.l
Normal file
@@ -0,0 +1,54 @@
|
||||
%{
|
||||
#include <tpr/tpr-scanner.hpp>
|
||||
#include <string>
|
||||
#undef YY_DECL
|
||||
#define YY_DECL int tpr::TempProfileScanner::yylex(tpr::TempProfileParser::semantic_type * const lval, tpr::TempProfileParser::location_type *loc )
|
||||
|
||||
#define YY_USER_ACTION loc->step(); loc->columns(yyleng);
|
||||
|
||||
using token = tpr::TempProfileParser::token;
|
||||
|
||||
%}
|
||||
|
||||
%option yyclass="tpr::TempProfileScanner"
|
||||
%option noyywrap
|
||||
%option never-interactive
|
||||
%option c++
|
||||
|
||||
/* Predefined rules */
|
||||
NEWLINE "\n"|"\r\n"
|
||||
COMMENT_LINE "#".*\n
|
||||
SPACE "\t"|" "
|
||||
|
||||
NUM_INT [-+]?([0-9]+)
|
||||
NUM_FLOAT [-+]?([0-9]*\.[0-9]+)
|
||||
|
||||
%%
|
||||
%{
|
||||
yylval = lval;
|
||||
%}
|
||||
|
||||
<*>{SPACE} { /*Ignore spaces */}
|
||||
{COMMENT_LINE} {loc->lines(); return token::lineend;}
|
||||
{NEWLINE} {loc->lines(); return token::lineend;}
|
||||
{NUM_FLOAT} {yylval->build<float>(std::stof(std::string(yytext))); return token::number_float;}
|
||||
{NUM_INT} {yylval->build<float>(std::stof(std::string(yytext))); return token::number_int;}
|
||||
|
||||
pid_conf { return token::kw_pid_conf; }
|
||||
temp_set { return token::kw_temp_set; }
|
||||
wait_temp { return token::kw_wait_temp; }
|
||||
wait_time { return token::kw_wait_time; }
|
||||
temp_ramp { return token::kw_temp_ramp; }
|
||||
beep { return token::kw_beep; }
|
||||
temp_off { return token::kw_temp_off; }
|
||||
clear_flags { return token::kw_clear_flags; }
|
||||
digio_conf { return token::kw_digio_conf; }
|
||||
digio_set { return token::kw_digio_set; }
|
||||
digio_wait { return token::kw_digio_wait; }
|
||||
|
||||
. {
|
||||
std::cerr << "[ERR] Failed to parse: " << yytext << " @ " << *loc << std::endl;
|
||||
return token::unexpected_input;
|
||||
}
|
||||
|
||||
%%
|
115
tprcc/parser/tpr.ypp
Normal file
115
tprcc/parser/tpr.ypp
Normal file
@@ -0,0 +1,115 @@
|
||||
|
||||
%language "c++"
|
||||
%require "3.2"
|
||||
%defines
|
||||
%define api.namespace {tpr}
|
||||
%define api.parser.class {TempProfileParser}
|
||||
|
||||
|
||||
%define parse.error verbose
|
||||
|
||||
%code requires{
|
||||
namespace tpr {
|
||||
class TempProfileScanner;
|
||||
}
|
||||
}
|
||||
|
||||
%parse-param { TempProfileScanner &scanner }
|
||||
|
||||
%code {
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <utility>
|
||||
#include <tuple>
|
||||
#include <tpr/tpr-scanner.hpp>
|
||||
#include <tpr/tpr-types.hpp>
|
||||
#undef yylex
|
||||
#define yylex scanner.yylex
|
||||
}
|
||||
|
||||
%define api.value.type variant
|
||||
%locations
|
||||
%start tpr_file
|
||||
|
||||
%token<float> number_float
|
||||
%token<float> number_int
|
||||
%token lineend
|
||||
%token kw_pid_conf
|
||||
%token kw_temp_set
|
||||
%token kw_wait_temp
|
||||
%token kw_wait_time
|
||||
%token kw_temp_ramp
|
||||
%token kw_beep
|
||||
%token kw_temp_off
|
||||
%token kw_clear_flags
|
||||
%token kw_digio_conf
|
||||
%token kw_digio_set
|
||||
%token kw_digio_wait
|
||||
%token unexpected_input
|
||||
|
||||
%type<float>number number_truncated
|
||||
|
||||
%%
|
||||
|
||||
tpr_file: tpr_command
|
||||
| tpr_file tpr_command
|
||||
;
|
||||
|
||||
|
||||
tpr_command: tpr_command_inner lineend
|
||||
| lineend
|
||||
;
|
||||
|
||||
tpr_command_inner: cmd_pid_conf;
|
||||
| cmd_temp_set
|
||||
| cmd_wait_temp
|
||||
| cmd_wait_time
|
||||
| cmd_temp_ramp
|
||||
| cmd_beep
|
||||
| cmd_temp_off
|
||||
| cmd_clear_flags
|
||||
| cmd_digio_conf
|
||||
| cmd_digio_set
|
||||
| cmd_digio_wait
|
||||
;
|
||||
|
||||
|
||||
cmd_pid_conf: kw_pid_conf number number number number number number;
|
||||
|
||||
cmd_temp_set: kw_temp_set number {std::cout << "Set Temperature" << $2 << std::endl;}
|
||||
;
|
||||
|
||||
cmd_wait_temp: kw_wait_temp number;
|
||||
|
||||
cmd_wait_time: kw_wait_time number;
|
||||
|
||||
cmd_temp_ramp: kw_temp_ramp number number;
|
||||
|
||||
cmd_beep: kw_beep number_truncated;
|
||||
|
||||
cmd_temp_off: kw_temp_off;
|
||||
|
||||
cmd_clear_flags: kw_clear_flags;
|
||||
|
||||
cmd_digio_conf: kw_digio_conf number_truncated number_truncated;
|
||||
|
||||
cmd_digio_set: kw_digio_set number_truncated number_truncated;
|
||||
|
||||
cmd_digio_wait: kw_digio_wait number_truncated number_truncated;
|
||||
|
||||
number_truncated: number_float {$$ = $1; std::cerr << "[WARN] Floating point number " << $1 << " will be truncated to an integer (" << (int)$1 << ") at location (" << @1 << ")" << std::endl;}
|
||||
| number_int {$$ = $1;}
|
||||
;
|
||||
|
||||
number: number_float {$$ = $1;}
|
||||
| number_int {$$ = $1;}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void tpr::TempProfileParser::error(const location_type &l, const std::string &err_message)
|
||||
{
|
||||
std::cerr << "[ERR] Parser Error: '" << err_message << "' at " << l << std::endl;
|
||||
std::abort();
|
||||
}
|
32
tprcc/src/logger.cpp
Normal file
32
tprcc/src/logger.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <tprcc/logger.hpp>
|
||||
#include <iostream>
|
||||
|
||||
Logger *Logger::logger_inst = nullptr;
|
||||
|
||||
Logger::Logger()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Logger *Logger::get_logger() {
|
||||
if (logger_inst == nullptr) {
|
||||
logger_inst = new Logger();
|
||||
}
|
||||
|
||||
return logger_inst;
|
||||
}
|
||||
|
||||
void Logger::log(LogLevel lvl, const std::string &message) const
|
||||
{
|
||||
switch (lvl) {
|
||||
case LogLevel::ERROR:
|
||||
std::cerr << "[ERR]" << message << std::endl;
|
||||
break;
|
||||
case LogLevel::WARNING:
|
||||
std::cerr << "[WARN]" << message << std::endl;
|
||||
break;
|
||||
default:
|
||||
std::cout << message << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
15
tprcc/src/main.cpp
Normal file
15
tprcc/src/main.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <iostream>
|
||||
#include <tpr/tpr-frontend.hpp>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
std::cout << "Hello world" << std::endl;
|
||||
|
||||
if (argc > 1) {
|
||||
auto fe = tpr::TprFrontend(std::string(argv[1]));
|
||||
|
||||
fe.analyze();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
27
tprcc/src/tpr/tpr-frontend.cpp
Normal file
27
tprcc/src/tpr/tpr-frontend.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <tprcc/logger.hpp>
|
||||
#include <tpr/tpr-frontend.hpp>
|
||||
|
||||
namespace tpr {
|
||||
|
||||
TprFrontend::TprFrontend(const std::string &source_file) : TempLangFrontend(source_file)
|
||||
{
|
||||
}
|
||||
|
||||
int TprFrontend::analyze()
|
||||
{
|
||||
std::ifstream input_stream(m_source_file);
|
||||
|
||||
if (!input_stream.good()) {
|
||||
Logger::get_logger()->log(LogLevel::ERROR, "Cannot read input file " + m_source_file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto scanner = TempProfileScanner(&input_stream);
|
||||
auto parser = TempProfileParser(scanner);
|
||||
|
||||
parser.parse();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
26
tprcc/src/tpr/tpr-types.cpp
Normal file
26
tprcc/src/tpr/tpr-types.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "tprcc/logger.hpp"
|
||||
#include <cstdlib>
|
||||
#include <tpr/tpr-types.hpp>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
namespace tpr {
|
||||
|
||||
|
||||
TprCommand::TprCommand(CommandType type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
TprCommand::TprCommand(CommandType type, const std::vector<float> ¶ms) : TprCommand(type)
|
||||
{
|
||||
m_parameters = params;
|
||||
}
|
||||
|
||||
TprCommand::TprCommand(CommandType type, const std::vector<float> &¶ms) : TprCommand(type)
|
||||
{
|
||||
m_parameters = std::move(params);
|
||||
}
|
||||
|
||||
|
||||
}
|
Reference in New Issue
Block a user