36 Commits

Author SHA1 Message Date
b5c002da5e Merge branch 'dev' into temp-profile-checker 2025-05-10 22:43:13 +02:00
fdc5bcdae3 Update the linked list library due to cmake problems 2025-05-10 22:43:01 +02:00
c3dd6248a3 Update bas64 library 2025-05-10 22:39:12 +02:00
6ca38419ad Merge branch 'dev' into temp-profile-checker 2025-05-10 22:35:27 +02:00
5c429ec894 Remove trailing whitespace 2024-03-24 14:13:56 +01:00
62ef147105 Incrment Cmake required version number 2024-03-24 14:11:33 +01:00
0e5ef46512 Restructure bison generation to allow multiple forntends 2024-01-22 21:20:10 +01:00
b83f057e49 Add logger singleton 2024-01-21 21:48:29 +01:00
fc2744d7fa Small progress. Have to continue here.. 2024-01-20 20:17:36 +01:00
223de7f190 Add first parser draft for temp prfiles. 2024-01-18 23:27:06 +01:00
dc6e973d52 Rename checker to tprcc 2024-01-18 20:27:17 +01:00
5b4dc705b4 Add grammar and tokens to parser and scanner 2024-01-17 22:43:30 +01:00
5190e3116b Add C++ template for lex / yacc setup 2024-01-17 20:28:40 +01:00
06893c21ab Merge branch 'dev' into temp-profile-checker 2024-01-17 19:25:46 +01:00
c6038969ca Fix style and code issues in bin2carray python script 2023-06-23 22:43:45 +02:00
0c8a0cd562 Fix watchdog tcode to write correct reload value 2023-06-09 00:12:41 +02:00
1300fe88a4 Shorten wtchdog trigger interval to 1.25 seconds nominal. This will ensure the internal watchdog triggers before the external one 2023-06-09 00:04:32 +02:00
df593e2ab2 Merge pull request 'misc-crc-monitor' (#55) from misc-crc-monitor into dev
Reviewed-on: #55
2023-05-23 19:07:21 +02:00
34ad930bd8 Fix mask for misc crc cfg monitor 2023-05-23 19:03:50 +02:00
1c1874abf1 Make safety flag ERR_FLAG_CFG_CRC_MISC trigger panic mode 2023-05-23 18:46:27 +02:00
fd2994f9b9 Add err flag cfg crc misc to flag list 2023-05-23 18:32:03 +02:00
b6befa70a2 Implement misc CRC monitor to supervise clocks and other system settings 2023-05-23 18:30:27 +02:00
dd6a7bef18 Merge pull request 'Pre-Release v0.5' (#54) from dev into master
Reviewed-on: #54
2023-01-03 16:37:53 +01:00
a005afaa13 Merge pull request 'Update FatFS in Firmware and Updater RAM Blob' (#53) from update-fatfs into dev
Reviewed-on: #53
2023-01-03 16:32:21 +01:00
cadd33d5a4 #48: Update FatFS in RAM code of updater 2023-01-03 15:08:57 +01:00
da132028b1 Issue #48: Update FatFS of main firmware to R0.15 2023-01-03 15:02:48 +01:00
2cd4847a57 Merge pull request 'version-rework' (#52) from version-rework into dev
Reviewed-on: #52
2023-01-01 21:23:32 +01:00
e335cb42ac Add comment to cmake build step 2023-01-01 21:16:36 +01:00
34c1c3db4e Rework UI to use newly created version handling 2023-01-01 21:12:19 +01:00
df70238b36 Remove git_ver define from updater 2023-01-01 21:12:00 +01:00
2c2e4c1484 Add compile date and time to version.c 2023-01-01 21:07:10 +01:00
767aa75c25 Make git a required build dependency 2023-01-01 21:04:03 +01:00
745e7db78f Add version c file that includes a generated file during build 2023-01-01 21:02:49 +01:00
9c0cbb107b Add script to generate header file containing version and commit hash 2023-01-01 20:45:57 +01:00
d48ccf1612 Fix #50: Enable core cycle counter 2023-01-01 20:18:39 +01:00
43b14bdb92 Start work on temperature profile checker 2022-06-09 17:50:33 +02:00
41 changed files with 1976 additions and 979 deletions

View File

@@ -38,9 +38,8 @@ if (GIT_FOUND)
)
message("${BoldGreen}Git based version number: ${GIT_DESCRIBE}${ColorReset}")
else (GIT_FOUND)
set(GIT_DESCRIBE "v0.0.0-unknown")
message("${BoldRed}No git installation found. It is highly recommended using git to generate the version number")
message("Version is set to: ${GIT_DESCRIBE}${ColorReset}")
message(FATAL_ERROR "Git is required")
endif (GIT_FOUND)
find_program(PATCHELFCRC patchelfcrc)
@@ -60,8 +59,7 @@ add_compile_options(-Wall -Wextra -Wold-style-declaration -Wuninitialized -Wmayb
add_compile_options(-mlittle-endian -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -nostartfiles -Wimplicit-fallthrough=3 -Wsign-compare)
set(GIT_DESCRIBE "${GIT_DESCRIBE}")
add_definitions(-DBASE64_LOOKUP_TABLE_SECTION=\".ccm.bss\" -DSHELLMATTA_HELP_ALIAS=\"?\" -DGIT_VER=${GIT_DESCRIBE} -DHSE_VALUE=8000000UL -DSTM32F407xx -DSTM32F4XX -DARM_MATH_CM4)
add_definitions(-DBASE64_LOOKUP_TABLE_SECTION=\".ccm.bss\" -DSHELLMATTA_HELP_ALIAS=\"?\" -DHSE_VALUE=8000000UL -DSTM32F407xx -DSTM32F4XX -DARM_MATH_CM4)
add_subdirectory(doxygen)
add_subdirectory(updater/ram-code)
@@ -101,18 +99,29 @@ aux_source_directory("shellmatta/src" SHELLMATTA_SRCS)
aux_source_directory("updater" UPDATER_SRCS)
aux_source_directory("temp-profile" PROFILE_SRCS)
set(GEN_VERSION_HEADER_PATH "${CMAKE_CURRENT_BINARY_DIR}/include/generated-version")
add_custom_target(
generate-version-header
COMMAND mkdir -p ${GEN_VERSION_HEADER_PATH} && bash "${CMAKE_CURRENT_SOURCE_DIR}/create_version_header.sh" "${GEN_VERSION_HEADER_PATH}/version.h"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating version number using git"
)
add_executable(${ELFFILE} ${MAIN_SOURCES} ${CFG_PARSER_SRCS} ${UI_SRCS}
${FAT_SRCS} ${SDIO_SRCS} ${BOOT_SRCS} ${SETUP_SRCS}
${STM_PERIPH_SRCS} ${SETTINGS_SRCS} ${SAFETY_SRCS}
${SHELLMATTA_SRCS} ${UPDATER_SRCS} ${PROFILE_SRCS}
)
add_dependencies(${ELFFILE} updater-ram-code-header-blob)
add_dependencies(${ELFFILE} updater-ram-code-header-blob generate-version-header)
target_include_directories(${ELFFILE} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/shellmatta/api ${CMAKE_CURRENT_SOURCE_DIR}/config-parser/include)
target_link_options(${ELFFILE} PRIVATE -mlittle-endian -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 --disable-newlib-supplied-syscalls -nostartfiles -T${LINKER_SCRIPT} -Wl,--print-memory-usage)
target_link_libraries(${ELFFILE} base64-lib linklist-lib)
target_include_directories(${ELFFILE} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/updater/ram-code/include/")
target_include_directories(${ELFFILE} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/updater/ram-code/include/" "${CMAKE_CURRENT_BINARY_DIR}/include/")
add_custom_command(
TARGET ${ELFFILE}

View File

@@ -0,0 +1,15 @@
#!/bin/bash
if [[ -z $1 ]]; then
# Exit with error in case no output file is specified
exit -1
fi
firmware_version=`git describe --tags --always --dirty`
commit=`git rev-parse HEAD`
echo "#ifndef _VERSION_GENERATED_H_" > $1
echo "#define _VERSION_GENERATED_H_" >> $1
echo "#define GIT_VERSION_STRING \"$firmware_version\"" >> $1
echo "#define GIT_FULL_COMMIT \"$commit\"" >> $1
echo "#endif /* _VERSION_GENERATED_H_ */" >> $1

File diff suppressed because it is too large Load Diff

View File

@@ -1,170 +1,208 @@
/*------------------------------------------------------------------------*/
/* Sample Code of OS Dependent Functions for FatFs */
/* (C)ChaN, 2018 */
/* A Sample Code of User Provided OS Dependent Functions for FatFs */
/*------------------------------------------------------------------------*/
#include <fatfs/ff.h>
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
#if FF_USE_LFN == 3 /* Use dynamic memory allocation */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/* Allocate/Free a Memory Block */
/*------------------------------------------------------------------------*/
#include <stdlib.h> /* with POSIX API */
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
UINT msize /* Number of bytes to allocate */
)
{
return malloc(msize); /* Allocate a new memory block with POSIX API */
return malloc((size_t)msize); /* Allocate a new memory block */
}
/*------------------------------------------------------------------------*/
/* Free a memory block */
/*------------------------------------------------------------------------*/
void ff_memfree (
void* mblock /* Pointer to the memory block to free (nothing to do if null) */
void* mblock /* Pointer to the memory block to free (no effect if null) */
)
{
free(mblock); /* Free the memory block with POSIX API */
free(mblock); /* Free the memory block */
}
#endif
#if FF_FS_REENTRANT /* Mutal exclusion */
/*------------------------------------------------------------------------*/
/* Create a Synchronization Object */
/* Definitions of Mutex */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to create a new
/ synchronization object for the volume, such as semaphore and mutex.
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
*/
//const osMutexDef_t Mutex[FF_VOLUMES]; /* Table of CMSIS-RTOS mutex */
#define OS_TYPE 0 /* 0:Win32, 1:uITRON4.0, 2:uC/OS-II, 3:FreeRTOS, 4:CMSIS-RTOS */
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
BYTE vol, /* Corresponding volume (logical drive number) */
FF_SYNC_t* sobj /* Pointer to return the created sync object */
)
{
/* Win32 */
*sobj = CreateMutex(NULL, FALSE, NULL);
return (int)(*sobj != INVALID_HANDLE_VALUE);
#if OS_TYPE == 0 /* Win32 */
#include <windows.h>
static HANDLE Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */
/* uITRON */
// T_CSEM csem = {TA_TPRI,1,1};
// *sobj = acre_sem(&csem);
// return (int)(*sobj > 0);
#elif OS_TYPE == 1 /* uITRON */
#include "itron.h"
#include "kernel.h"
static mtxid Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */
/* uC/OS-II */
// OS_ERR err;
// *sobj = OSMutexCreate(0, &err);
// return (int)(err == OS_NO_ERR);
#elif OS_TYPE == 2 /* uc/OS-II */
#include "includes.h"
static OS_EVENT *Mutex[FF_VOLUMES + 1]; /* Table of mutex pinter */
/* FreeRTOS */
// *sobj = xSemaphoreCreateMutex();
// return (int)(*sobj != NULL);
#elif OS_TYPE == 3 /* FreeRTOS */
#include "FreeRTOS.h"
#include "semphr.h"
static SemaphoreHandle_t Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */
/* CMSIS-RTOS */
// *sobj = osMutexCreate(&Mutex[vol]);
// return (int)(*sobj != NULL);
}
/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
)
{
/* Win32 */
return (int)CloseHandle(sobj);
/* uITRON */
// return (int)(del_sem(sobj) == E_OK);
/* uC/OS-II */
// OS_ERR err;
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
// vSemaphoreDelete(sobj);
// return 1;
/* CMSIS-RTOS */
// return (int)(osMutexDelete(sobj) == osOK);
}
/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on entering file functions to lock the volume.
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
*/
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
FF_SYNC_t sobj /* Sync object to wait */
)
{
/* Win32 */
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
/* uITRON */
// return (int)(wai_sem(sobj) == E_OK);
/* uC/OS-II */
// OS_ERR err;
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
/* CMSIS-RTOS */
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
}
/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/
void ff_rel_grant (
FF_SYNC_t sobj /* Sync object to be signaled */
)
{
/* Win32 */
ReleaseMutex(sobj);
/* uITRON */
// sig_sem(sobj);
/* uC/OS-II */
// OSMutexPost(sobj);
/* FreeRTOS */
// xSemaphoreGive(sobj);
/* CMSIS-RTOS */
// osMutexRelease(sobj);
}
#elif OS_TYPE == 4 /* CMSIS-RTOS */
#include "cmsis_os.h"
static osMutexId Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */
#endif
/*------------------------------------------------------------------------*/
/* Create a Mutex */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount function to create a new mutex
/ or semaphore for the volume. When a 0 is returned, the f_mount function
/ fails with FR_INT_ERR.
*/
int ff_mutex_create ( /* Returns 1:Function succeeded or 0:Could not create the mutex */
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
)
{
#if OS_TYPE == 0 /* Win32 */
Mutex[vol] = CreateMutex(NULL, FALSE, NULL);
return (int)(Mutex[vol] != INVALID_HANDLE_VALUE);
#elif OS_TYPE == 1 /* uITRON */
T_CMTX cmtx = {TA_TPRI,1};
Mutex[vol] = acre_mtx(&cmtx);
return (int)(Mutex[vol] > 0);
#elif OS_TYPE == 2 /* uC/OS-II */
OS_ERR err;
Mutex[vol] = OSMutexCreate(0, &err);
return (int)(err == OS_NO_ERR);
#elif OS_TYPE == 3 /* FreeRTOS */
Mutex[vol] = xSemaphoreCreateMutex();
return (int)(Mutex[vol] != NULL);
#elif OS_TYPE == 4 /* CMSIS-RTOS */
osMutexDef(cmsis_os_mutex);
Mutex[vol] = osMutexCreate(osMutex(cmsis_os_mutex));
return (int)(Mutex[vol] != NULL);
#endif
}
/*------------------------------------------------------------------------*/
/* Delete a Mutex */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount function to delete a mutex or
/ semaphore of the volume created with ff_mutex_create function.
*/
void ff_mutex_delete ( /* Returns 1:Function succeeded or 0:Could not delete due to an error */
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
)
{
#if OS_TYPE == 0 /* Win32 */
CloseHandle(Mutex[vol]);
#elif OS_TYPE == 1 /* uITRON */
del_mtx(Mutex[vol]);
#elif OS_TYPE == 2 /* uC/OS-II */
OS_ERR err;
OSMutexDel(Mutex[vol], OS_DEL_ALWAYS, &err);
#elif OS_TYPE == 3 /* FreeRTOS */
vSemaphoreDelete(Mutex[vol]);
#elif OS_TYPE == 4 /* CMSIS-RTOS */
osMutexDelete(Mutex[vol]);
#endif
}
/*------------------------------------------------------------------------*/
/* Request a Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on enter file functions to lock the volume.
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
*/
int ff_mutex_take ( /* Returns 1:Succeeded or 0:Timeout */
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
)
{
#if OS_TYPE == 0 /* Win32 */
return (int)(WaitForSingleObject(Mutex[vol], FF_FS_TIMEOUT) == WAIT_OBJECT_0);
#elif OS_TYPE == 1 /* uITRON */
return (int)(tloc_mtx(Mutex[vol], FF_FS_TIMEOUT) == E_OK);
#elif OS_TYPE == 2 /* uC/OS-II */
OS_ERR err;
OSMutexPend(Mutex[vol], FF_FS_TIMEOUT, &err));
return (int)(err == OS_NO_ERR);
#elif OS_TYPE == 3 /* FreeRTOS */
return (int)(xSemaphoreTake(Mutex[vol], FF_FS_TIMEOUT) == pdTRUE);
#elif OS_TYPE == 4 /* CMSIS-RTOS */
return (int)(osMutexWait(Mutex[vol], FF_FS_TIMEOUT) == osOK);
#endif
}
/*------------------------------------------------------------------------*/
/* Release a Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leave file functions to unlock the volume.
*/
void ff_mutex_give (
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
)
{
#if OS_TYPE == 0 /* Win32 */
ReleaseMutex(Mutex[vol]);
#elif OS_TYPE == 1 /* uITRON */
unl_mtx(Mutex[vol]);
#elif OS_TYPE == 2 /* uC/OS-II */
OSMutexPost(Mutex[vol]);
#elif OS_TYPE == 3 /* FreeRTOS */
xSemaphoreGive(Mutex[vol]);
#elif OS_TYPE == 4 /* CMSIS-RTOS */
osMutexRelease(Mutex[vol]);
#endif
}
#endif /* FF_FS_REENTRANT */

View File

@@ -1,13 +1,13 @@
/*------------------------------------------------------------------------*/
/* Unicode handling functions for FatFs R0.13+ */
/* Unicode Handling Functions for FatFs R0.13 and Later */
/*------------------------------------------------------------------------*/
/* This module will occupy a huge memory in the .rodata section when the */
/* FatFs is configured for LFN with DBCS. If the system has a Unicode */
/* library for the code conversion, this module should be modified to use */
/* it to avoid silly memory consumption. */
/*------------------------------------------------------------------------*/
/* This module will occupy a huge memory in the .const section when the /
/ FatFs is configured for LFN with DBCS. If the system has any Unicode /
/ utilitiy for the code conversion, this module should be modified to use /
/ that function to avoid silly memory consumption. /
/-------------------------------------------------------------------------*/
/*
/ Copyright (C) 2014, ChaN, all right reserved.
/ Copyright (C) 2022, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
@@ -25,7 +25,7 @@
#include <fatfs/ff.h>
#if FF_USE_LFN /* This module will be blanked if non-LFN configuration */
#if FF_USE_LFN != 0 /* This module will be blanked if in non-LFN configuration */
#define MERGE2(a, b) a ## b
#define CVTBL(tbl, cp) MERGE2(tbl, cp)
@@ -15214,8 +15214,8 @@ static const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */
/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions for static code page configuration */
/* SBCS fixed code page */
/* OEM <==> Unicode Conversions for Static Code Page Configuration with */
/* SBCS Fixed Code Page */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900
@@ -15225,7 +15225,7 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
)
{
WCHAR c = 0;
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
const WCHAR* p = CVTBL(uc, FF_CODE_PAGE);
if (uni < 0x80) { /* ASCII? */
@@ -15247,7 +15247,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
)
{
WCHAR c = 0;
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
const WCHAR* p = CVTBL(uc, FF_CODE_PAGE);
if (oem < 0x80) { /* ASCII? */
@@ -15267,8 +15267,8 @@ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions for static code page configuration */
/* DBCS fixed code page */
/* OEM <==> Unicode Conversions for Static Code Page Configuration with */
/* DBCS Fixed Code Page */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE >= 900
@@ -15277,7 +15277,7 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
const WCHAR* p;
WCHAR c = 0, uc;
UINT i = 0, n, li, hi;
@@ -15313,7 +15313,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
const WCHAR* p;
WCHAR c = 0;
UINT i = 0, n, li, hi;
@@ -15346,7 +15346,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions for dynamic code page configuration */
/* OEM <==> Unicode Conversions for Dynamic Code Page Configuration */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE == 0
@@ -15360,7 +15360,7 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
const WCHAR* p;
WCHAR c = 0, uc;
UINT i, n, li, hi;
@@ -15412,7 +15412,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
const WCHAR* p;
WCHAR c = 0;
UINT i, n, li, hi;
@@ -15458,14 +15458,14 @@ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
/*------------------------------------------------------------------------*/
/* Unicode up-case conversion */
/* Unicode Up-case Conversion */
/*------------------------------------------------------------------------*/
DWORD ff_wtoupper ( /* Returns up-converted code point */
DWORD uni /* Unicode code point to be up-converted */
)
{
const WORD *p;
const WORD* p;
WORD uc, bc, nc, cmd;
static const WORD cvt1[] = { /* Compressed up conversion table for U+0000 - U+0FFF */
/* Basic Latin */
@@ -15590,4 +15590,4 @@ DWORD ff_wtoupper ( /* Returns up-converted code point */
}
#endif /* #if FF_USE_LFN */
#endif /* #if FF_USE_LFN != 0 */

View File

@@ -1,8 +1,8 @@
/*----------------------------------------------------------------------------/
/ FatFs - Generic FAT Filesystem module R0.14b /
/ FatFs - Generic FAT Filesystem module R0.15 /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2021, ChaN, all right reserved.
/ Copyright (C) 2022, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
@@ -20,7 +20,7 @@
#ifndef FF_DEFINED
#define FF_DEFINED 86631 /* Revision ID */
#define FF_DEFINED 80286 /* Revision ID */
#ifdef __cplusplus
extern "C" {
@@ -131,10 +131,11 @@ extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
typedef struct {
BYTE fs_type; /* Filesystem type (0:not mounted) */
BYTE pdrv; /* Associated physical drive */
BYTE pdrv; /* Volume hosting physical drive */
BYTE ldrv; /* Logical drive number (used only when FF_FS_REENTRANT) */
BYTE n_fats; /* Number of FATs (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
BYTE wflag; /* win[] status (b0:dirty) */
BYTE fsi_flag; /* FSINFO status (b7:disabled, b0:dirty) */
WORD id; /* Volume mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
WORD csize; /* Cluster size [sectors] */
@@ -147,9 +148,6 @@ typedef struct {
#if FF_FS_EXFAT
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
#endif
#if FF_FS_REENTRANT
FF_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !FF_FS_READONLY
DWORD last_clst; /* Last allocated cluster */
DWORD free_clst; /* Number of free clusters */
@@ -163,10 +161,10 @@ typedef struct {
#endif
#endif
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
DWORD fsize; /* Size of an FAT [sectors] */
DWORD fsize; /* Number of sectors per FAT */
LBA_t volbase; /* Volume base sector */
LBA_t fatbase; /* FAT base sector */
LBA_t dirbase; /* Root directory base sector/cluster */
LBA_t dirbase; /* Root directory base sector (FAT12/16) or cluster (FAT32/exFAT) */
LBA_t database; /* Data base sector */
#if FF_FS_EXFAT
LBA_t bitbase; /* Allocation bitmap base sector */
@@ -181,7 +179,7 @@ typedef struct {
typedef struct {
FATFS* fs; /* Pointer to the hosting volume of this object */
WORD id; /* Hosting volume mount ID */
WORD id; /* Hosting volume's mount ID */
BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
@@ -250,7 +248,7 @@ typedef struct {
WORD ftime; /* Modified time */
BYTE fattrib; /* File attribute */
#if FF_USE_LFN
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
TCHAR altname[FF_SFN_BUF + 1];/* Alternative file name */
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
#else
TCHAR fname[12 + 1]; /* File name */
@@ -298,8 +296,10 @@ typedef enum {
/*--------------------------------------------------------------*/
/* FatFs Module Application Interface */
/*--------------------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
FRESULT f_close (FIL* fp); /* Close an open file object */
@@ -336,6 +336,8 @@ int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
/* Some API fucntions are implemented as macro */
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
#define f_error(fp) ((fp)->err)
#define f_tell(fp) ((fp)->fptr)
@@ -349,38 +351,43 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the fil
/*--------------------------------------------------------------*/
/* Additional user defined functions */
/* Additional Functions */
/*--------------------------------------------------------------*/
/* RTC function */
/* RTC function (provided by user) */
#if !FF_FS_READONLY && !FF_FS_NORTC
DWORD get_fattime (void);
DWORD get_fattime (void); /* Get current time */
#endif
/* LFN support functions */
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
/* LFN support functions (defined in ffunicode.c) */
#if FF_USE_LFN >= 1
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
#endif
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
void* ff_memalloc (UINT msize); /* Allocate memory block */
void ff_memfree (void* mblock); /* Free memory block */
#endif
/* Sync functions */
#if FF_FS_REENTRANT
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
/* O/S dependent functions (samples available in ffsystem.c) */
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
void* ff_memalloc (UINT msize); /* Allocate memory block */
void ff_memfree (void* mblock); /* Free memory block */
#endif
#if FF_FS_REENTRANT /* Sync functions */
int ff_mutex_create (int vol); /* Create a sync object */
void ff_mutex_delete (int vol); /* Delete a sync object */
int ff_mutex_take (int vol); /* Lock sync object */
void ff_mutex_give (int vol); /* Unlock sync object */
#endif
/*--------------------------------------------------------------*/
/* Flags and offset address */
/* Flags and Offset Address */
/*--------------------------------------------------------------*/
/* File access mode and open method flags (3rd argument of f_open) */
#define FA_READ 0x01

View File

@@ -1,8 +1,8 @@
/*---------------------------------------------------------------------------/
/ FatFs Functional Configurations
/ Configurations of FatFs Module
/---------------------------------------------------------------------------*/
#define FFCONF_DEF 86631 /* Revision ID */
#define FFCONF_DEF 80286 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Function Configurations
@@ -68,7 +68,7 @@
/ 2: Enable with LF-CRLF conversion.
/
/ FF_PRINT_LLI = 1 makes f_printf() support long long argument and FF_PRINT_FLOAT = 1/2
makes f_printf() support floating point argument. These features want C99 or later.
/ makes f_printf() support floating point argument. These features want C99 or later.
/ When FF_LFN_UNICODE >= 1 with LFN enabled, string functions convert the character
/ encoding in it. FF_STRF_ENCODE selects assumption of character encoding ON THE FILE
/ to be read/written via those functions.
@@ -178,7 +178,7 @@
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
/ not defined, a user defined volume string table needs to be defined as:
/ not defined, a user defined volume string table is needed as:
/
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
*/
@@ -190,7 +190,7 @@
/ number and only an FAT volume found on the physical drive will be mounted.
/ When this function is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
/ function will be available. */
#define FF_MIN_SS 512
@@ -240,10 +240,10 @@
#define FF_FS_NORTC 0
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2020
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
#define FF_NORTC_YEAR 2022
/* The option FF_FS_NORTC switches timestamp feature. If the system does not have
/ an RTC or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable the
/ timestamp feature. Every object modified by FatFs will have a fixed timestamp
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
@@ -253,7 +253,7 @@
#define FF_FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ option, and f_getfree() function at the first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
@@ -275,26 +275,21 @@
/ lock control is independent of re-entrancy. */
/* #include <somertos.h> // O/S definitions */
#define FF_FS_REENTRANT 0
#define FF_FS_TIMEOUT 1000
#define FF_SYNC_t HANDLE
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/ to the same volume is under control of this featuer.
/
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
/ 0: Disable re-entrancy. FF_FS_TIMEOUT have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/ ff_mutex_create(), ff_mutex_delete(), ff_mutex_take() and ff_mutex_give()
/ function, must be added to the project. Samples are available in ffsystem.c.
/
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
/ The FF_FS_TIMEOUT defines timeout period in unit of O/S time tick.
*/

View File

@@ -30,10 +30,16 @@
#include <stdint.h>
/**
* @brief Initialize/Reset the main cycle counter to 0.
* @brief Initialize the main cycle counter and reset to 0. This also enables the core cycle counter
* This function can be called multiple times.
*/
void main_cycle_counter_init(void);
void main_and_core_cycle_counter_init(void);
/**
* @brief Reset the main cycle counter.
* @note This does not reset the core cycle counter
*/
void main_cycle_counter_reset(void);
/**
* @brief Increment the main cycle counter by 1
@@ -46,6 +52,18 @@ void main_cycle_counter_inc(void);
*/
uint64_t main_cycle_counter_get(void);
/**
* @brief Reset the core cycle counter to 0
*/
void core_cycle_counter_reset(void);
/**
* @brief Get the current value of the core cycle counter
*
* @return uint32_t Counter value
*/
uint32_t core_cycle_counter_get(void);
#endif /* __MAIN_CYCLE_COUNTER_H__ */
/** @} */

View File

@@ -69,6 +69,7 @@ enum safety_flag {
ERR_FLAG_FLASH_CRC_DATA = (1<<20),
ERR_FLAG_CFG_CRC_MEAS_ADC = (1<<21),
ERR_FLAG_CFG_CRC_SAFETY_ADC = (1<<22),
ERR_FLAG_CFG_CRC_MISC = (1<<23),
};
/**
@@ -87,6 +88,7 @@ enum timing_monitor {
enum crc_monitor {
ERR_CRC_MON_MEAS_ADC = 0,
ERR_CRC_MON_SAFETY_ADC,
ERR_CRC_MON_MISC,
N_ERR_CRC_MON
};
@@ -124,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
@@ -167,6 +177,12 @@ enum analog_value_monitor {
*/
#define SAFETY_CRC_MON_SAFETY_ADC_PW 0xA8DF2368
/**
* @brief Password for resetting ERR_CRC_MON_MISC
*
*/
#define SAFETY_CRC_MON_MISC_PW 0x9A62E96A
/**
* @brief Default persistence of safety flags. These values are loaded into the safety tables on startup.
*/
@@ -192,7 +208,8 @@ enum analog_value_monitor {
ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_FLASH_CRC_CODE, true), \
ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_FLASH_CRC_DATA, true), \
ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_CFG_CRC_MEAS_ADC, true), \
ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_CFG_CRC_SAFETY_ADC, true)
ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_CFG_CRC_SAFETY_ADC, true), \
ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_CFG_CRC_MISC, true),
/**
* @brief Default config weights of safety flags. These values are loaded into the safety tables on startup.
*/
@@ -218,6 +235,7 @@ enum analog_value_monitor {
ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_FLASH_CRC_CODE, SAFETY_FLAG_CONFIG_WEIGHT_PANIC), \
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_SAFETY_ADC, SAFETY_FLAG_CONFIG_WEIGHT_PANIC), \
ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_CFG_CRC_MISC, SAFETY_FLAG_CONFIG_WEIGHT_PANIC)
#endif /* __SAFETY_CONFIG_H__ */

View File

@@ -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

View File

@@ -0,0 +1,29 @@
/* Reflow Oven Controller
*
* Copyright (C) 2022 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/>.
*/
#ifndef _VERSION_H_
#define _VERSION_H_
extern const char *version_git_version_string;
extern const char *version_git_full_commit_string;
extern const char *version_compile_date;
extern const char *version_compile_time;
#endif /* _VERSION_H_ */

View File

@@ -25,6 +25,7 @@
#include <reflow-controller/main-cycle-counter.h>
#include <helper-macros/helper-macros.h>
#include <stm32/stm32f4xx.h>
/**
* @brief Variable storing the main cycle counter.
@@ -33,7 +34,22 @@
*/
static uint64_t IN_SECTION(.ccm.bss) main_cycle_counter;
void main_cycle_counter_init(void)
void main_and_core_cycle_counter_init(void)
{
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
/* Enable the core cycle counter if available on current processor */
if (!(DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk)) {
/* Cycle counter is available. Enable */
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
/* Reset the counters to 0 */
main_cycle_counter_reset();
core_cycle_counter_reset();
}
void main_cycle_counter_reset(void)
{
main_cycle_counter = 0ULL;
}
@@ -48,4 +64,14 @@ uint64_t main_cycle_counter_get(void)
return main_cycle_counter;
}
void core_cycle_counter_reset(void)
{
DWT->CYCCNT = 0UL;
}
uint32_t core_cycle_counter_get(void)
{
return DWT->CYCCNT;
}
/** @} */

View File

@@ -23,6 +23,7 @@
* @brief Main file for firmware
*/
#include "reflow-controller/safety/safety-config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -215,6 +216,9 @@ static inline void setup_system(void)
/** - Enable the ADC for PT1000 measurement */
adc_pt1000_setup_meas();
/** - Enable the misc CRC config monitor to supervise clock, systick and flash settings */
(void)safety_controller_set_crc_monitor(ERR_CRC_MON_MISC, SAFETY_CRC_MON_MISC_PW);
}
/**
@@ -268,8 +272,8 @@ int main(void)
/** - Print motd to shell */
shell_print_motd(shell_handle);
/** - Set the main cycle counter to 0 */
main_cycle_counter_init();
/** - Set the main cycle counter to 0 and activate the core cycle counter if available */
main_and_core_cycle_counter_init();
/** - Do a loop over the following */
while (1) {

View File

@@ -23,6 +23,7 @@
* @{
*/
#include "stm32/stm32f407xx.h"
#include <reflow-controller/safety/safety-controller.h>
#include <reflow-controller/safety/safety-config.h>
#include <reflow-controller/safety/watchdog.h>
@@ -163,9 +164,15 @@ struct crc_monitor_register {
#define CRC_MON_REGISTER_ENTRY(_addr, _mask, _size) {.reg_addr = &(_addr), .mask = (_mask), .size = (_size)}
/**
* @brief Sentinel Element for crc monitor register list
*
*/
#define CRC_MON_REGISTER_SENTINEL {.reg_addr = NULL, .mask = 0, .size = 0}
struct crc_mon {
/**
* @brief Array of registers to monitor. Terminated by NULL sentinel!
* @brief Array of registers to monitor. Terminated by NULL sentinel @ref CRC_MON_REGISTER_SENTINEL
*/
const struct crc_monitor_register *registers;
const enum crc_monitor monitor;
@@ -204,6 +211,7 @@ static volatile struct error_flag IN_SECTION(.ccm.data) flags[] = {
ERR_FLAG_ENTRY(ERR_FLAG_FLASH_CRC_DATA),
ERR_FLAG_ENTRY(ERR_FLAG_CFG_CRC_MEAS_ADC),
ERR_FLAG_ENTRY(ERR_FLAG_CFG_CRC_SAFETY_ADC),
ERR_FLAG_ENTRY(ERR_FLAG_CFG_CRC_MISC),
};
/**
@@ -291,7 +299,7 @@ static const struct crc_monitor_register meas_adc_crc_regs[] = {
ADC_SQR2_SQ8 | ADC_SQR2_SQ7, 4),
CRC_MON_REGISTER_ENTRY(ADC_PT1000_PERIPH->SQR3, ADC_SQR3_SQ6 | ADC_SQR3_SQ5 | ADC_SQR3_SQ4 |
ADC_SQR3_SQ3 | ADC_SQR3_SQ2 | ADC_SQR3_SQ1, 4),
{NULL, 0, 0}
CRC_MON_REGISTER_SENTINEL
};
static const struct crc_monitor_register safety_adc_crc_regs[] = {
@@ -307,7 +315,24 @@ static const struct crc_monitor_register safety_adc_crc_regs[] = {
ADC_SQR2_SQ8 | ADC_SQR2_SQ7, 4),
CRC_MON_REGISTER_ENTRY(SAFETY_ADC_ADC_PERIPHERAL->SQR3, ADC_SQR3_SQ6 | ADC_SQR3_SQ5 | ADC_SQR3_SQ4 |
ADC_SQR3_SQ3 | ADC_SQR3_SQ2 | ADC_SQR3_SQ1, 4),
{NULL, 0, 0}
CRC_MON_REGISTER_ENTRY(RCC->APB2ENR, SAFETY_ADC_ADC_RCC_MASK, 4),
CRC_MON_REGISTER_SENTINEL
};
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 */
CRC_MON_REGISTER_ENTRY(FLASH->ACR, FLASH_ACR_LATENCY | FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_PRFTEN, 4),
/* Check vector table offset */
CRC_MON_REGISTER_ENTRY(SCB->VTOR, 0xFFFFFFFF, 4),
/* Check system tick configuration */
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
};
static struct crc_mon IN_SECTION(.ccm.data) crc_monitors[] = {
@@ -331,6 +356,16 @@ static struct crc_mon IN_SECTION(.ccm.data) crc_monitors[] = {
.last_crc = 0UL,
.active = false,
},
{
.registers = misc_config_crc_regs,
.monitor = ERR_CRC_MON_MISC,
.pw = SAFETY_CRC_MON_MISC_PW,
.flag_to_set = ERR_FLAG_CFG_CRC_MISC,
.expected_crc = 0UL,
.expected_crc_inv = ~0UL,
.last_crc = 0UL,
.active = false,
}
};
/**
@@ -938,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);

View File

@@ -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)

View File

@@ -18,6 +18,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "reflow-controller/version.h"
#include <reflow-controller/ui/gui.h>
#include <reflow-controller/ui/gui-config.h>
#include <reflow-controller/ui/menu.h>
@@ -167,9 +168,9 @@ static void gui_menu_about(struct lcd_menu *menu, enum menu_entry_func_entry ent
break;
last_page = 1;
menu_lcd_output(menu, 0, "Version Number:");
menu_lcd_outputf(menu, 1, "%.*s", LCD_CHAR_WIDTH, xstr(GIT_VER));
if (strlen(xstr(GIT_VER)) > LCD_CHAR_WIDTH) {
menu_lcd_outputf(menu, 2, "%s", &xstr(GIT_VER)[LCD_CHAR_WIDTH]);
menu_lcd_outputf(menu, 1, "%.*s", LCD_CHAR_WIDTH, version_git_version_string);
if (strlen(version_git_version_string) > LCD_CHAR_WIDTH) {
menu_lcd_outputf(menu, 2, "%s", &version_git_version_string[LCD_CHAR_WIDTH]);
}
#ifdef DEBUGBUILD
menu_lcd_output(menu, 3, "Page 2/5 [DEBUG]");

View File

@@ -49,13 +49,10 @@
#include <reflow-controller/ui/gui.h>
#include <reflow-controller/ui/shell-uart.h>
#include <reflow-controller/safety/flash-crc.h>
#include <reflow-controller/version.h>
#include <stdio.h>
#ifndef GIT_VER
#define GIT_VER "VERSION NOT SET"
#endif
static shellmatta_instance_t shell;
static char shell_buffer[512];
static char IN_SECTION(.ccm.bss) history_buffer[512];
@@ -81,8 +78,9 @@ static shellmatta_retCode_t shell_cmd_ver(const shellmatta_handle_t handle,
stm_unique_id_get(&high_id, &mid_id, &low_id);
stm_dev_rev_id_get(&stm_dev_id, &stm_rev_id);
shellmatta_printf(handle, "Reflow Oven Controller Firmware " xstr(GIT_VER) "\r\n"
"Compiled: " __DATE__ " at " __TIME__ "\r\n");
shellmatta_printf(handle, "Reflow Oven Controller Firmware %s\r\n"
"Compiled: %s at %s\r\n",
version_git_version_string, version_compile_date, version_compile_time);
shellmatta_printf(handle, "Serial: %08X-%08X-%08X\r\n", high_id, mid_id, low_id);
pcb_rev = get_pcb_hardware_version();
@@ -892,7 +890,7 @@ shellmatta_retCode_t shell_cmd_cycle_count(const shellmatta_handle_t handle, con
counter = main_cycle_counter_get();
core_cycle_count = DWT->CYCCNT;
core_cycle_count = core_cycle_counter_get();
if (hex) {
shellmatta_printf(handle, "Main loop: 0x%016"PRIX64"\r\n", counter);
shellmatta_printf(handle, "CPU cycles: 0x%08"PRIX32"\r\n", core_cycle_count);
@@ -901,8 +899,8 @@ shellmatta_retCode_t shell_cmd_cycle_count(const shellmatta_handle_t handle, con
shellmatta_printf(handle, "CPU cycles: %"PRIu32"\r\n", core_cycle_count);
}
if (clear) {
main_cycle_counter_init();
DWT->CYCCNT = 0UL;
main_cycle_counter_reset();
core_cycle_counter_reset();
}
return SHELLMATTA_OK;
}

View File

@@ -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")
@@ -31,7 +31,7 @@ add_executable(${ELFFILE} ${SRCS} ${FATFS_SRCS} ${SDIO_SRCS} ${STM_PERIPH_SRCS}
target_include_directories(${ELFFILE} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ../../include ${CMAKE_CURRENT_SOURCE_DIR}/3rd-party)
target_compile_options(${ELFFILE} PRIVATE -Wall -Wextra -Wold-style-declaration -Wuninitialized -Wmaybe-uninitialized -Wunused-parameter)
target_compile_options(${ELFFILE} PRIVATE -mlittle-endian -mthumb -mcpu=cortex-m4 -mthumb-interwork -mfloat-abi=hard -mfpu=fpv4-sp-d16 -nostartfiles -Wimplicit-fallthrough=3 -Wsign-compare -Os -g3)
target_compile_definitions(${ELFFILE} PRIVATE -DGIT_VER=${GIT_DESCRIBE} -DHSE_VALUE=8000000UL -DSTM32F407xx -DSTM32F4XX -DARM_MATH_CM4 -DSAFETY_MEMORY_STRIPOUT_DUMP)
target_compile_definitions(${ELFFILE} PRIVATE -DHSE_VALUE=8000000UL -DSTM32F407xx -DSTM32F4XX -DARM_MATH_CM4 -DSAFETY_MEMORY_STRIPOUT_DUMP)
target_link_options(${ELFFILE} PRIVATE -mlittle-endian -mthumb -mcpu=cortex-m4 -mthumb-interwork -mfloat-abi=hard -mfpu=fpv4-sp-d16 --disable-newlib-supplied-syscalls -nostartfiles -T${LINKER_SCRIPT} -Wl,--print-memory-usage)
set(GEN_HEADER_PATH "${CMAKE_CURRENT_BINARY_DIR}/include/generated")
set(GEN_HEADER_FILE "${GEN_HEADER_PATH}/${PROJECT_NAME}.bin.h")

View File

@@ -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())

File diff suppressed because it is too large Load Diff

View File

@@ -1,170 +1,208 @@
/*------------------------------------------------------------------------*/
/* Sample Code of OS Dependent Functions for FatFs */
/* (C)ChaN, 2018 */
/* A Sample Code of User Provided OS Dependent Functions for FatFs */
/*------------------------------------------------------------------------*/
#include <fatfs/ff.h>
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
#if FF_USE_LFN == 3 /* Use dynamic memory allocation */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/* Allocate/Free a Memory Block */
/*------------------------------------------------------------------------*/
#include <stdlib.h> /* with POSIX API */
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
UINT msize /* Number of bytes to allocate */
)
{
return malloc(msize); /* Allocate a new memory block with POSIX API */
return malloc((size_t)msize); /* Allocate a new memory block */
}
/*------------------------------------------------------------------------*/
/* Free a memory block */
/*------------------------------------------------------------------------*/
void ff_memfree (
void* mblock /* Pointer to the memory block to free (nothing to do if null) */
void* mblock /* Pointer to the memory block to free (no effect if null) */
)
{
free(mblock); /* Free the memory block with POSIX API */
free(mblock); /* Free the memory block */
}
#endif
#if FF_FS_REENTRANT /* Mutal exclusion */
/*------------------------------------------------------------------------*/
/* Create a Synchronization Object */
/* Definitions of Mutex */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to create a new
/ synchronization object for the volume, such as semaphore and mutex.
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
*/
//const osMutexDef_t Mutex[FF_VOLUMES]; /* Table of CMSIS-RTOS mutex */
#define OS_TYPE 0 /* 0:Win32, 1:uITRON4.0, 2:uC/OS-II, 3:FreeRTOS, 4:CMSIS-RTOS */
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
BYTE vol, /* Corresponding volume (logical drive number) */
FF_SYNC_t* sobj /* Pointer to return the created sync object */
)
{
/* Win32 */
*sobj = CreateMutex(NULL, FALSE, NULL);
return (int)(*sobj != INVALID_HANDLE_VALUE);
#if OS_TYPE == 0 /* Win32 */
#include <windows.h>
static HANDLE Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */
/* uITRON */
// T_CSEM csem = {TA_TPRI,1,1};
// *sobj = acre_sem(&csem);
// return (int)(*sobj > 0);
#elif OS_TYPE == 1 /* uITRON */
#include "itron.h"
#include "kernel.h"
static mtxid Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */
/* uC/OS-II */
// OS_ERR err;
// *sobj = OSMutexCreate(0, &err);
// return (int)(err == OS_NO_ERR);
#elif OS_TYPE == 2 /* uc/OS-II */
#include "includes.h"
static OS_EVENT *Mutex[FF_VOLUMES + 1]; /* Table of mutex pinter */
/* FreeRTOS */
// *sobj = xSemaphoreCreateMutex();
// return (int)(*sobj != NULL);
#elif OS_TYPE == 3 /* FreeRTOS */
#include "FreeRTOS.h"
#include "semphr.h"
static SemaphoreHandle_t Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */
/* CMSIS-RTOS */
// *sobj = osMutexCreate(&Mutex[vol]);
// return (int)(*sobj != NULL);
}
/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
)
{
/* Win32 */
return (int)CloseHandle(sobj);
/* uITRON */
// return (int)(del_sem(sobj) == E_OK);
/* uC/OS-II */
// OS_ERR err;
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
// vSemaphoreDelete(sobj);
// return 1;
/* CMSIS-RTOS */
// return (int)(osMutexDelete(sobj) == osOK);
}
/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on entering file functions to lock the volume.
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
*/
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
FF_SYNC_t sobj /* Sync object to wait */
)
{
/* Win32 */
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
/* uITRON */
// return (int)(wai_sem(sobj) == E_OK);
/* uC/OS-II */
// OS_ERR err;
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
/* CMSIS-RTOS */
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
}
/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/
void ff_rel_grant (
FF_SYNC_t sobj /* Sync object to be signaled */
)
{
/* Win32 */
ReleaseMutex(sobj);
/* uITRON */
// sig_sem(sobj);
/* uC/OS-II */
// OSMutexPost(sobj);
/* FreeRTOS */
// xSemaphoreGive(sobj);
/* CMSIS-RTOS */
// osMutexRelease(sobj);
}
#elif OS_TYPE == 4 /* CMSIS-RTOS */
#include "cmsis_os.h"
static osMutexId Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */
#endif
/*------------------------------------------------------------------------*/
/* Create a Mutex */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount function to create a new mutex
/ or semaphore for the volume. When a 0 is returned, the f_mount function
/ fails with FR_INT_ERR.
*/
int ff_mutex_create ( /* Returns 1:Function succeeded or 0:Could not create the mutex */
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
)
{
#if OS_TYPE == 0 /* Win32 */
Mutex[vol] = CreateMutex(NULL, FALSE, NULL);
return (int)(Mutex[vol] != INVALID_HANDLE_VALUE);
#elif OS_TYPE == 1 /* uITRON */
T_CMTX cmtx = {TA_TPRI,1};
Mutex[vol] = acre_mtx(&cmtx);
return (int)(Mutex[vol] > 0);
#elif OS_TYPE == 2 /* uC/OS-II */
OS_ERR err;
Mutex[vol] = OSMutexCreate(0, &err);
return (int)(err == OS_NO_ERR);
#elif OS_TYPE == 3 /* FreeRTOS */
Mutex[vol] = xSemaphoreCreateMutex();
return (int)(Mutex[vol] != NULL);
#elif OS_TYPE == 4 /* CMSIS-RTOS */
osMutexDef(cmsis_os_mutex);
Mutex[vol] = osMutexCreate(osMutex(cmsis_os_mutex));
return (int)(Mutex[vol] != NULL);
#endif
}
/*------------------------------------------------------------------------*/
/* Delete a Mutex */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount function to delete a mutex or
/ semaphore of the volume created with ff_mutex_create function.
*/
void ff_mutex_delete ( /* Returns 1:Function succeeded or 0:Could not delete due to an error */
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
)
{
#if OS_TYPE == 0 /* Win32 */
CloseHandle(Mutex[vol]);
#elif OS_TYPE == 1 /* uITRON */
del_mtx(Mutex[vol]);
#elif OS_TYPE == 2 /* uC/OS-II */
OS_ERR err;
OSMutexDel(Mutex[vol], OS_DEL_ALWAYS, &err);
#elif OS_TYPE == 3 /* FreeRTOS */
vSemaphoreDelete(Mutex[vol]);
#elif OS_TYPE == 4 /* CMSIS-RTOS */
osMutexDelete(Mutex[vol]);
#endif
}
/*------------------------------------------------------------------------*/
/* Request a Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on enter file functions to lock the volume.
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
*/
int ff_mutex_take ( /* Returns 1:Succeeded or 0:Timeout */
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
)
{
#if OS_TYPE == 0 /* Win32 */
return (int)(WaitForSingleObject(Mutex[vol], FF_FS_TIMEOUT) == WAIT_OBJECT_0);
#elif OS_TYPE == 1 /* uITRON */
return (int)(tloc_mtx(Mutex[vol], FF_FS_TIMEOUT) == E_OK);
#elif OS_TYPE == 2 /* uC/OS-II */
OS_ERR err;
OSMutexPend(Mutex[vol], FF_FS_TIMEOUT, &err));
return (int)(err == OS_NO_ERR);
#elif OS_TYPE == 3 /* FreeRTOS */
return (int)(xSemaphoreTake(Mutex[vol], FF_FS_TIMEOUT) == pdTRUE);
#elif OS_TYPE == 4 /* CMSIS-RTOS */
return (int)(osMutexWait(Mutex[vol], FF_FS_TIMEOUT) == osOK);
#endif
}
/*------------------------------------------------------------------------*/
/* Release a Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leave file functions to unlock the volume.
*/
void ff_mutex_give (
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
)
{
#if OS_TYPE == 0 /* Win32 */
ReleaseMutex(Mutex[vol]);
#elif OS_TYPE == 1 /* uITRON */
unl_mtx(Mutex[vol]);
#elif OS_TYPE == 2 /* uC/OS-II */
OSMutexPost(Mutex[vol]);
#elif OS_TYPE == 3 /* FreeRTOS */
xSemaphoreGive(Mutex[vol]);
#elif OS_TYPE == 4 /* CMSIS-RTOS */
osMutexRelease(Mutex[vol]);
#endif
}
#endif /* FF_FS_REENTRANT */

View File

@@ -1,13 +1,13 @@
/*------------------------------------------------------------------------*/
/* Unicode handling functions for FatFs R0.13+ */
/* Unicode Handling Functions for FatFs R0.13 and Later */
/*------------------------------------------------------------------------*/
/* This module will occupy a huge memory in the .rodata section when the */
/* FatFs is configured for LFN with DBCS. If the system has a Unicode */
/* library for the code conversion, this module should be modified to use */
/* it to avoid silly memory consumption. */
/*------------------------------------------------------------------------*/
/* This module will occupy a huge memory in the .const section when the /
/ FatFs is configured for LFN with DBCS. If the system has any Unicode /
/ utilitiy for the code conversion, this module should be modified to use /
/ that function to avoid silly memory consumption. /
/-------------------------------------------------------------------------*/
/*
/ Copyright (C) 2014, ChaN, all right reserved.
/ Copyright (C) 2022, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
@@ -22,10 +22,9 @@
/ by use of this software.
*/
#include <fatfs/ff.h>
#if FF_USE_LFN /* This module will be blanked if non-LFN configuration */
#if FF_USE_LFN != 0 /* This module will be blanked if in non-LFN configuration */
#define MERGE2(a, b) a ## b
#define CVTBL(tbl, cp) MERGE2(tbl, cp)
@@ -15214,8 +15213,8 @@ static const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */
/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions for static code page configuration */
/* SBCS fixed code page */
/* OEM <==> Unicode Conversions for Static Code Page Configuration with */
/* SBCS Fixed Code Page */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900
@@ -15225,7 +15224,7 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
)
{
WCHAR c = 0;
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
const WCHAR* p = CVTBL(uc, FF_CODE_PAGE);
if (uni < 0x80) { /* ASCII? */
@@ -15247,7 +15246,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
)
{
WCHAR c = 0;
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
const WCHAR* p = CVTBL(uc, FF_CODE_PAGE);
if (oem < 0x80) { /* ASCII? */
@@ -15267,8 +15266,8 @@ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions for static code page configuration */
/* DBCS fixed code page */
/* OEM <==> Unicode Conversions for Static Code Page Configuration with */
/* DBCS Fixed Code Page */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE >= 900
@@ -15277,7 +15276,7 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
const WCHAR* p;
WCHAR c = 0, uc;
UINT i = 0, n, li, hi;
@@ -15313,7 +15312,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
const WCHAR* p;
WCHAR c = 0;
UINT i = 0, n, li, hi;
@@ -15346,7 +15345,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions for dynamic code page configuration */
/* OEM <==> Unicode Conversions for Dynamic Code Page Configuration */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE == 0
@@ -15360,7 +15359,7 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
const WCHAR* p;
WCHAR c = 0, uc;
UINT i, n, li, hi;
@@ -15412,7 +15411,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
const WCHAR* p;
WCHAR c = 0;
UINT i, n, li, hi;
@@ -15458,14 +15457,14 @@ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
/*------------------------------------------------------------------------*/
/* Unicode up-case conversion */
/* Unicode Up-case Conversion */
/*------------------------------------------------------------------------*/
DWORD ff_wtoupper ( /* Returns up-converted code point */
DWORD uni /* Unicode code point to be up-converted */
)
{
const WORD *p;
const WORD* p;
WORD uc, bc, nc, cmd;
static const WORD cvt1[] = { /* Compressed up conversion table for U+0000 - U+0FFF */
/* Basic Latin */
@@ -15590,4 +15589,4 @@ DWORD ff_wtoupper ( /* Returns up-converted code point */
}
#endif /* #if FF_USE_LFN */
#endif /* #if FF_USE_LFN != 0 */

View File

@@ -1,8 +1,8 @@
/*----------------------------------------------------------------------------/
/ FatFs - Generic FAT Filesystem module R0.14b /
/ FatFs - Generic FAT Filesystem module R0.15 /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2021, ChaN, all right reserved.
/ Copyright (C) 2022, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
@@ -20,7 +20,7 @@
#ifndef FF_DEFINED
#define FF_DEFINED 86631 /* Revision ID */
#define FF_DEFINED 80286 /* Revision ID */
#ifdef __cplusplus
extern "C" {
@@ -131,10 +131,11 @@ extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
typedef struct {
BYTE fs_type; /* Filesystem type (0:not mounted) */
BYTE pdrv; /* Associated physical drive */
BYTE pdrv; /* Volume hosting physical drive */
BYTE ldrv; /* Logical drive number (used only when FF_FS_REENTRANT) */
BYTE n_fats; /* Number of FATs (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
BYTE wflag; /* win[] status (b0:dirty) */
BYTE fsi_flag; /* FSINFO status (b7:disabled, b0:dirty) */
WORD id; /* Volume mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
WORD csize; /* Cluster size [sectors] */
@@ -147,9 +148,6 @@ typedef struct {
#if FF_FS_EXFAT
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
#endif
#if FF_FS_REENTRANT
FF_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !FF_FS_READONLY
DWORD last_clst; /* Last allocated cluster */
DWORD free_clst; /* Number of free clusters */
@@ -163,10 +161,10 @@ typedef struct {
#endif
#endif
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
DWORD fsize; /* Size of an FAT [sectors] */
DWORD fsize; /* Number of sectors per FAT */
LBA_t volbase; /* Volume base sector */
LBA_t fatbase; /* FAT base sector */
LBA_t dirbase; /* Root directory base sector/cluster */
LBA_t dirbase; /* Root directory base sector (FAT12/16) or cluster (FAT32/exFAT) */
LBA_t database; /* Data base sector */
#if FF_FS_EXFAT
LBA_t bitbase; /* Allocation bitmap base sector */
@@ -181,7 +179,7 @@ typedef struct {
typedef struct {
FATFS* fs; /* Pointer to the hosting volume of this object */
WORD id; /* Hosting volume mount ID */
WORD id; /* Hosting volume's mount ID */
BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
@@ -250,7 +248,7 @@ typedef struct {
WORD ftime; /* Modified time */
BYTE fattrib; /* File attribute */
#if FF_USE_LFN
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
TCHAR altname[FF_SFN_BUF + 1];/* Alternative file name */
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
#else
TCHAR fname[12 + 1]; /* File name */
@@ -298,8 +296,10 @@ typedef enum {
/*--------------------------------------------------------------*/
/* FatFs Module Application Interface */
/*--------------------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
FRESULT f_close (FIL* fp); /* Close an open file object */
@@ -336,6 +336,8 @@ int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
/* Some API fucntions are implemented as macro */
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
#define f_error(fp) ((fp)->err)
#define f_tell(fp) ((fp)->fptr)
@@ -349,38 +351,43 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the fil
/*--------------------------------------------------------------*/
/* Additional user defined functions */
/* Additional Functions */
/*--------------------------------------------------------------*/
/* RTC function */
/* RTC function (provided by user) */
#if !FF_FS_READONLY && !FF_FS_NORTC
DWORD get_fattime (void);
DWORD get_fattime (void); /* Get current time */
#endif
/* LFN support functions */
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
/* LFN support functions (defined in ffunicode.c) */
#if FF_USE_LFN >= 1
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
#endif
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
void* ff_memalloc (UINT msize); /* Allocate memory block */
void ff_memfree (void* mblock); /* Free memory block */
#endif
/* Sync functions */
#if FF_FS_REENTRANT
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
/* O/S dependent functions (samples available in ffsystem.c) */
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
void* ff_memalloc (UINT msize); /* Allocate memory block */
void ff_memfree (void* mblock); /* Free memory block */
#endif
#if FF_FS_REENTRANT /* Sync functions */
int ff_mutex_create (int vol); /* Create a sync object */
void ff_mutex_delete (int vol); /* Delete a sync object */
int ff_mutex_take (int vol); /* Lock sync object */
void ff_mutex_give (int vol); /* Unlock sync object */
#endif
/*--------------------------------------------------------------*/
/* Flags and offset address */
/* Flags and Offset Address */
/*--------------------------------------------------------------*/
/* File access mode and open method flags (3rd argument of f_open) */
#define FA_READ 0x01

View File

@@ -1,8 +1,8 @@
/*---------------------------------------------------------------------------/
/ FatFs Functional Configurations
/ Configurations of FatFs Module
/---------------------------------------------------------------------------*/
#define FFCONF_DEF 86631 /* Revision ID */
#define FFCONF_DEF 80286 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Function Configurations
@@ -68,7 +68,7 @@
/ 2: Enable with LF-CRLF conversion.
/
/ FF_PRINT_LLI = 1 makes f_printf() support long long argument and FF_PRINT_FLOAT = 1/2
makes f_printf() support floating point argument. These features want C99 or later.
/ makes f_printf() support floating point argument. These features want C99 or later.
/ When FF_LFN_UNICODE >= 1 with LFN enabled, string functions convert the character
/ encoding in it. FF_STRF_ENCODE selects assumption of character encoding ON THE FILE
/ to be read/written via those functions.
@@ -178,7 +178,7 @@
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
/ not defined, a user defined volume string table needs to be defined as:
/ not defined, a user defined volume string table is needed as:
/
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
*/
@@ -190,7 +190,7 @@
/ number and only an FAT volume found on the physical drive will be mounted.
/ When this function is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
/ function will be available. */
#define FF_MIN_SS 512
@@ -240,10 +240,10 @@
#define FF_FS_NORTC 0
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2020
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
#define FF_NORTC_YEAR 2022
/* The option FF_FS_NORTC switches timestamp feature. If the system does not have
/ an RTC or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable the
/ timestamp feature. Every object modified by FatFs will have a fixed timestamp
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
@@ -253,7 +253,7 @@
#define FF_FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ option, and f_getfree() function at the first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
@@ -275,26 +275,21 @@
/ lock control is independent of re-entrancy. */
/* #include <somertos.h> // O/S definitions */
#define FF_FS_REENTRANT 0
#define FF_FS_TIMEOUT 1000
#define FF_SYNC_t HANDLE
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/ to the same volume is under control of this featuer.
/
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
/ 0: Disable re-entrancy. FF_FS_TIMEOUT have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/ ff_mutex_create(), ff_mutex_delete(), ff_mutex_take() and ff_mutex_give()
/ function, must be added to the project. Samples are available in ffsystem.c.
/
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
/ The FF_FS_TIMEOUT defines timeout period in unit of O/S time tick.
*/

27
stm-firmware/version.c Normal file
View File

@@ -0,0 +1,27 @@
/* Reflow Oven Controller
*
* Copyright (C) 2022 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/>.
*/
#include <reflow-controller/version.h>
#include <generated-version/version.h>
const char *version_git_version_string = GIT_VERSION_STRING;
const char *version_git_full_commit_string = GIT_FULL_COMMIT;
const char *version_compile_date = __DATE__;
const char *version_compile_time = __TIME__;

3
tprcc/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*.o
build/*
.cache/*

46
tprcc/CMakeLists.txt Normal file
View 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
View 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"

View 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_ */

View 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_ */

View 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_ */

View 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> &params);
TprCommand(CommandType type, const std::vector<float> &&params);
};
}
#endif /* _TPR_TYPES_HPP_ */

View 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
View 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
View 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
View 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
View 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;
}

View 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;
}
}

View 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> &params) : TprCommand(type)
{
m_parameters = params;
}
TprCommand::TprCommand(CommandType type, const std::vector<float> &&params) : TprCommand(type)
{
m_parameters = std::move(params);
}
}