Compare commits
39 Commits
bb0ea908cb
...
v0.3
Author | SHA1 | Date | |
---|---|---|---|
00b8d1f48e | |||
8ac1d52240 | |||
3e82cf69b4 | |||
62b256fd18 | |||
74111826a0 | |||
69d7724c8f | |||
48f69d0fb5 | |||
8fd924829e | |||
ba8072c21d | |||
5ddae7efee | |||
14ea4d22fe | |||
d5780500f3 | |||
d4d654e8dd | |||
8a62ed2ea7 | |||
7d43b4130c | |||
835faf7e4e | |||
2957a42cef | |||
1e45c8b5d7 | |||
3bb4607798 | |||
a8a622df25 | |||
45f91a7c5a | |||
bf6a222c9d | |||
ef534746f8 | |||
8cd47aeed5 | |||
1291b0fb6a | |||
b6a2790a59 | |||
7bfa0732db | |||
0dace23021 | |||
c78477296a | |||
96e0931c9f | |||
6b9b7d78a0 | |||
22bb227bc7 | |||
78f24f7338 | |||
e3a552248d | |||
288b19c4fc | |||
56872086fa | |||
fe0e8136d4 | |||
73606bf7a0 | |||
78501143cc |
Submodule c-style-checker updated: cb937262aa...aeb2707d80
@@ -15,4 +15,4 @@ mechanisms and the behavior. For a detailed code documentation see the doxygen o
|
||||
safety/index
|
||||
code/index
|
||||
hw-version-detect
|
||||
|
||||
peripherals
|
||||
|
44
doc/source/firmware/peripherals.rst
Normal file
44
doc/source/firmware/peripherals.rst
Normal file
@@ -0,0 +1,44 @@
|
||||
.. _peripherals:
|
||||
|
||||
Used Peripheral Modules
|
||||
=======================
|
||||
|
||||
This section lists all the used peripheral modules of the ``STM32F407VxT6``.
|
||||
|
||||
Core Peripherals
|
||||
----------------
|
||||
|
||||
- ``SysTick``: Generating a 100us tick for the LCD routine and 1ms base system tick.
|
||||
- ``NVIC``: Interrupt controller
|
||||
- ``FPU``: The Flaoting Point Unit is activated and used in this formware.
|
||||
|
||||
AHB Peripherals
|
||||
---------------
|
||||
|
||||
- ``DMA2``
|
||||
- ``Stream0``: DMA transfer of PT1000 measurement ADC to memory
|
||||
- ``Stream4``: DMA transfer of Safety ADC measurement values
|
||||
- ``Stream5``: Shell UART RX
|
||||
- ``Stream7``: Shell UART TX
|
||||
- ``RNG``: Random number generation for stack corruption / overflow checker.
|
||||
- ``CRC``: CRC verfication of various data (Safety structures, EEPROM data, Safety RAM)
|
||||
- ``Backup RAM``: Backup RAM storing errors and bootloader information beyond system resets. The memory is cleared by a power cycle!
|
||||
|
||||
ABP1 Peripherals
|
||||
----------------
|
||||
|
||||
- ``IWDG``: Independent Watchdog
|
||||
- ``TIM2``: PT1000 measurement ADC sample time generation timer. Genewrates the 1 KHz sample trigger to the ADC peripheral via the internal event routing system.
|
||||
- ``TIM3``: PWM timer for oven relais output.
|
||||
- ``TIM5``: Input capture for rotary encoder.
|
||||
- ``TIM7``: Timer for loudspeaker tone generation.
|
||||
|
||||
|
||||
APB2 Peripherals
|
||||
----------------
|
||||
|
||||
- ``SPI1``: SPI for external SPI-EEPROM
|
||||
- ``SDIO``: SD card interface
|
||||
- ``USART1``: Shell UART
|
||||
- ``ADC1``: Safety ADC for monitoring voltages
|
||||
- ``ADC3``: PT1000 measurement ADC
|
@@ -324,7 +324,6 @@ void __attribute__((noreturn)) Reset_Handler(void) {
|
||||
/* Move the stack and the stack pointer to CCMRAM
|
||||
* This allows us to perform a RAM test on the main RAM.
|
||||
*/
|
||||
/* R2 holds the amount of bytes / words on the stack. */
|
||||
__asm__ __volatile__ (
|
||||
"mov r2, sp\n" /* Move stack pointer to register 2 */
|
||||
"sub r2, %[stacktop], r2\n" /* Subtract stackpointer from top of ram => byte usage */
|
||||
|
@@ -31,10 +31,17 @@
|
||||
#define CONFIG_PARSER_MAGIC 0x464a6e2bUL
|
||||
#define CONFIG_PARSER(p) ((struct config_parser *)(p))
|
||||
|
||||
#define config_parser_check_handle(handle) do { if (!(handle) || \
|
||||
((struct config_parser *)(handle))->magic != CONFIG_PARSER_MAGIC) \
|
||||
return CONFIG_PARSER_PARAM_ERR; \
|
||||
} while (0)
|
||||
/**
|
||||
* @brief Check if the supplied pointer is a valid @ref config_parser_handle_t
|
||||
*
|
||||
* If the pointer is invalid, the function using this macro will return with
|
||||
* CONFIG_PARSER_PARAM_ERR
|
||||
*/
|
||||
#define config_parser_check_handle(handle) do { \
|
||||
if (!(handle) || \
|
||||
((struct config_parser *)(handle))->magic != CONFIG_PARSER_MAGIC) \
|
||||
return CONFIG_PARSER_PARAM_ERR; \
|
||||
} while (0)
|
||||
|
||||
config_parser_handle_t config_parser_open_file(struct config_parser *config_parser, bool write, const char *file_name,
|
||||
char *working_buffer, size_t buff_size)
|
||||
@@ -56,9 +63,18 @@ config_parser_handle_t config_parser_open_file(struct config_parser *config_pars
|
||||
return (config_parser_handle_t)config_parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Token delimiters for the config parser.
|
||||
*/
|
||||
static const char * const token_delim = " \t";
|
||||
|
||||
static int parse_value(struct config_parser_entry *entry, char *value_start_token)
|
||||
/**
|
||||
* @brief Parse a value in the configuration
|
||||
* @param entry Entry to parse the value in to
|
||||
* @param value_start_token char pointer holding the value. Must be null-terminated
|
||||
* @return 0 if successful
|
||||
*/
|
||||
static int parse_value(struct config_parser_entry *entry, char *value_start_token)
|
||||
{
|
||||
char *dot;
|
||||
char *endptr;
|
||||
@@ -76,19 +92,18 @@ static int parse_value(struct config_parser_entry *entry, char *value_start_tok
|
||||
|
||||
if (value_start_token[0] != '-') {
|
||||
/* Try parsing as ul */
|
||||
/* Try parsing as int */
|
||||
entry->value.uint_val = strtoul(value_start_token, &endptr, 0);
|
||||
if (endptr == value_start_token) {
|
||||
if (endptr == value_start_token)
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry->type = CONFIG_PARSER_TYPE_UINT;
|
||||
goto exit;
|
||||
} else {
|
||||
/* Try parsing as int */
|
||||
entry->value.int_val = strtod(value_start_token, &endptr);
|
||||
if (endptr == value_start_token) {
|
||||
if (endptr == value_start_token)
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry->type = CONFIG_PARSER_TYPE_INT;
|
||||
}
|
||||
|
||||
@@ -96,14 +111,16 @@ exit:
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum config_parser_ret config_parser_get_line(config_parser_handle_t handle, struct config_parser_entry *entry, bool force_float)
|
||||
enum config_parser_ret config_parser_get_line(config_parser_handle_t handle, struct config_parser_entry *entry,
|
||||
bool force_float)
|
||||
{
|
||||
struct config_parser *p;
|
||||
config_parser_check_handle(handle);
|
||||
p = CONFIG_PARSER(handle);
|
||||
char *token;
|
||||
int token_round = 0;
|
||||
|
||||
config_parser_check_handle(handle);
|
||||
p = CONFIG_PARSER(handle);
|
||||
|
||||
if (!entry)
|
||||
return CONFIG_PARSER_PARAM_ERR;
|
||||
|
||||
@@ -117,8 +134,7 @@ enum config_parser_ret config_parser_get_line(config_parser_handle_t handle, str
|
||||
if (token[0] == '#') {
|
||||
if (token_round == 0)
|
||||
return CONFIG_PARSER_LINE_COMMENT;
|
||||
else
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (token_round) {
|
||||
@@ -126,9 +142,8 @@ enum config_parser_ret config_parser_get_line(config_parser_handle_t handle, str
|
||||
entry->name = token;
|
||||
break;
|
||||
case 1: /* = Symbol */
|
||||
if (strcmp(token, "=")) {
|
||||
if (strcmp(token, "="))
|
||||
return CONFIG_PARSER_LINE_MALFORM;
|
||||
}
|
||||
break;
|
||||
case 2: /* VALUE */
|
||||
if (parse_value(entry, token))
|
||||
@@ -158,6 +173,7 @@ enum config_parser_ret config_parser_reset_to_start(config_parser_handle_t handl
|
||||
{
|
||||
FRESULT res;
|
||||
struct config_parser *p;
|
||||
|
||||
config_parser_check_handle(handle);
|
||||
p = CONFIG_PARSER(handle);
|
||||
|
||||
@@ -180,6 +196,7 @@ enum config_parser_ret config_parser_close_file(config_parser_handle_t handle)
|
||||
{
|
||||
struct config_parser *p;
|
||||
FRESULT res;
|
||||
|
||||
config_parser_check_handle(handle);
|
||||
p = CONFIG_PARSER(handle);
|
||||
|
||||
|
@@ -33,44 +33,68 @@
|
||||
#include <stdbool.h>
|
||||
#include <fatfs/ff.h>
|
||||
|
||||
/**
|
||||
* @brief Confi parser instance struct
|
||||
*/
|
||||
struct config_parser {
|
||||
uint32_t magic;
|
||||
bool write;
|
||||
FIL file;
|
||||
char *buffer;
|
||||
size_t buff_size;
|
||||
uint32_t magic; /**< @brief Magic value. Checked by each function to verify if the passed pointer is valid */
|
||||
bool write; /**< @brief File opened in write / read mode */
|
||||
FIL file; /**< @brief FatFS file */
|
||||
char *buffer; /**< @brief Working buffer */
|
||||
size_t buff_size; /** @brief Size of the working buffer config_parser::buffer */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief handle type for the config parser. Never dereference this pointer directly!
|
||||
*/
|
||||
typedef void * config_parser_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Differnet value types a config entry can hold
|
||||
*/
|
||||
enum config_parser_value_type {
|
||||
CONFIG_PARSER_TYPE_UINT = 0,
|
||||
CONFIG_PARSER_TYPE_INT,
|
||||
CONFIG_PARSER_TYPE_FLOAT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Error return code of config parser functions
|
||||
*/
|
||||
enum config_parser_ret {
|
||||
CONFIG_PARSER_OK = 0,
|
||||
CONFIG_PARSER_PARAM_ERR,
|
||||
CONFIG_PARSER_GENERIC_ERR,
|
||||
CONFIG_PARSER_IOERR,
|
||||
CONFIG_PARSER_LINE_COMMENT,
|
||||
CONFIG_PARSER_LINE_TOO_LONG,
|
||||
CONFIG_PARSER_LINE_MALFORM,
|
||||
CONFIG_PARSER_END_REACHED,
|
||||
CONFIG_PARSER_WRONG_MODE,
|
||||
CONFIG_PARSER_OK = 0, /**< @brief Operation succeeded */
|
||||
CONFIG_PARSER_PARAM_ERR, /**< @brief Function parameter error */
|
||||
CONFIG_PARSER_GENERIC_ERR, /**< @brief Generic unspecified error */
|
||||
CONFIG_PARSER_IOERR, /**< @brief I/O Error while file handling */
|
||||
CONFIG_PARSER_LINE_COMMENT, /**< @brief The parser encountered a line starting with a comment. */
|
||||
CONFIG_PARSER_LINE_TOO_LONG, /**< @brief The read line is too long for the parser to process. */
|
||||
CONFIG_PARSER_LINE_MALFORM, /**< @brief Malfoirmed line. Line is neither a commenbt nor a key=value string */
|
||||
CONFIG_PARSER_END_REACHED, /**< @brief The config parser has reached the end of the file */
|
||||
CONFIG_PARSER_WRONG_MODE, /**< @brief Read or write requested on config parser instance that is opened in a different mode */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a configuration key-value-pair used by the config parser
|
||||
*/
|
||||
struct config_parser_entry {
|
||||
const char *name;
|
||||
enum config_parser_value_type type;
|
||||
const char *name; /**< @brief Pointer to the name of the config entry (key) */
|
||||
enum config_parser_value_type type; /**< @brief Type of the value held by this struct */
|
||||
union {
|
||||
uint32_t uint_val;
|
||||
int32_t int_val;
|
||||
float float_val;
|
||||
} value;
|
||||
} value; /**< @brief Value of the config entry. For correct processing, config_parser_entry::type has to be taken into account */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Open a config file
|
||||
* @param config_parser Struict holding the config parser isntance. Will be filled by this function
|
||||
* @param write Open the config file for writing (true) or reading (false)
|
||||
* @param file_name File name to open
|
||||
* @param working_buffer A working buffer used by the config parser to process the file.
|
||||
* @param buff_size Size of \p working_buffer. Must be large enough to hold a full line of the config file
|
||||
* @return Config parser error
|
||||
*/
|
||||
config_parser_handle_t config_parser_open_file(struct config_parser *config_parser, bool write, const char *file_name,
|
||||
char *working_buffer, size_t buff_size);
|
||||
|
||||
@@ -83,13 +107,37 @@ config_parser_handle_t config_parser_open_file(struct config_parser *config_pars
|
||||
* @return Config parser error
|
||||
*/
|
||||
enum config_parser_ret config_parser_get_line(config_parser_handle_t handle, struct config_parser_entry *entry, bool force_float);
|
||||
|
||||
/**
|
||||
* @brief Reset the config parser instance to the beginning of the config file
|
||||
* @param handle Config parser
|
||||
* @return Config parser error
|
||||
*/
|
||||
enum config_parser_ret config_parser_reset_to_start(config_parser_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Write a config entry to a config file
|
||||
* @param handle Handle to the config parser. This must be opened in write mode.
|
||||
* @param entry
|
||||
* @return Config parser error
|
||||
* @warning This function is currently not implemented and will return with a success!
|
||||
*/
|
||||
enum config_parser_ret config_parser_write_entry(config_parser_handle_t handle, const struct config_parser_entry *entry);
|
||||
|
||||
/**
|
||||
* @brief Close a config parser handle
|
||||
* @param handle Config parser
|
||||
* @return Config parser error
|
||||
*/
|
||||
enum config_parser_ret config_parser_close_file(config_parser_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Check if the \p return_val is a abort condition to stop parsing a file.
|
||||
*
|
||||
* This function will return true if a disk error occured or the end of file is reached.
|
||||
*
|
||||
* @param return_val
|
||||
* @return
|
||||
*/
|
||||
bool config_parser_ret_is_abort_condition(enum config_parser_ret return_val);
|
||||
|
||||
#endif /* _CONFIG_PARSER_H_ */
|
||||
|
@@ -89,7 +89,8 @@ with open(filename, 'r+b') as f:
|
||||
print('Section for flash CRC missing!')
|
||||
sys.exit(-1)
|
||||
if flashcrc_sec.data_size != 6*4:
|
||||
print("Warning!!! .flashcrc section has wrong size:",flashcrc_sec.data_size)
|
||||
print("Error: .flashcrc section has wrong size:",flashcrc_sec.data_size)
|
||||
sys.exit(-1);
|
||||
|
||||
crc_sec_data = bytearray(flashcrc_sec.data())
|
||||
magic1 = struct.unpack('<I'*1, bytes(crc_sec_data[0:4]))[0]
|
||||
@@ -110,4 +111,4 @@ with open(filename, 'r+b') as f:
|
||||
f.write(crc_sec_data)
|
||||
print('CRCs patched successfully')
|
||||
|
||||
|
||||
|
||||
|
@@ -52,17 +52,10 @@ static void digio_setup_pin_int(uint8_t bit_no, uint8_t in_out, uint8_t alt_func
|
||||
|
||||
}
|
||||
|
||||
void digio_setup_default_all(void)
|
||||
void digio_init(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(DIGIO_RCC_MASK));
|
||||
|
||||
for (i = 0; i < COUNT_OF(digio_pins); i++) {
|
||||
digio_setup_pin_int(digio_pins[i], digio_default_io[i], digio_default_altfunc[i]);
|
||||
if (digio_default_io[i] == 1)
|
||||
digio_set(i, 0);
|
||||
}
|
||||
digio_set_default_values();
|
||||
}
|
||||
|
||||
void digio_setup_pin(uint8_t num, uint8_t in_out, uint8_t alt_func)
|
||||
@@ -74,12 +67,22 @@ void digio_setup_pin(uint8_t num, uint8_t in_out, uint8_t alt_func)
|
||||
|
||||
void digio_set(uint8_t num, int val)
|
||||
{
|
||||
uint8_t pin;
|
||||
|
||||
if (num >= COUNT_OF(digio_pins))
|
||||
return;
|
||||
|
||||
pin = digio_pins[num];
|
||||
|
||||
/* Check if port is an output. If not, do noting. */
|
||||
if ((DIGIO_PORT->MODER & (0x3<<pin)) != OUTPUT(pin)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (val)
|
||||
DIGIO_PORT->ODR |= (1<<digio_pins[num]);
|
||||
DIGIO_PORT->ODR |= (1<<pin);
|
||||
else
|
||||
DIGIO_PORT->ODR &= ~(1<<digio_pins[num]);
|
||||
DIGIO_PORT->ODR &= ~(1<<pin);
|
||||
}
|
||||
|
||||
int digio_get(uint8_t num)
|
||||
@@ -219,3 +222,14 @@ void TIM7_IRQHandler(void)
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
void digio_set_default_values()
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < COUNT_OF(digio_pins); i++) {
|
||||
digio_setup_pin_int(digio_pins[i], digio_default_io[i], digio_default_altfunc[i]);
|
||||
if (digio_default_io[i] == 1)
|
||||
digio_set(i, 0);
|
||||
}
|
||||
}
|
||||
|
24
stm-firmware/fatfs/LICENSE.txt
Normal file
24
stm-firmware/fatfs/LICENSE.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
FatFs License
|
||||
|
||||
FatFs has being developped as a personal project of the author, ChaN. It is free from the code anyone else wrote at current release. Following code block shows a copy of the FatFs license document that heading the source files.
|
||||
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem Module Rx.xx /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 20xx, 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
|
||||
/ that the following condition is met:
|
||||
/
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
Therefore FatFs license is one of the BSD-style licenses, but there is a significant feature. FatFs is mainly intended for embedded systems. In order to extend the usability for commercial products, the redistributions of FatFs in binary form, such as embedded code, binary library and any forms without source code, do not need to include about FatFs in the documentations. This is equivalent to the 1-clause BSD license. Of course FatFs is compatible with the most of open source software licenses include GNU GPL. When you redistribute the FatFs source code with changes or create a fork, the license can also be changed to GNU GPL, BSD-style license or any open source software license that not conflict with FatFs license.
|
File diff suppressed because it is too large
Load Diff
@@ -33,6 +33,9 @@ enum hw_revision get_pcb_hardware_version(void)
|
||||
uint16_t port_bitmask = 0U;
|
||||
static enum hw_revision revision = HW_REV_NOT_DETECTED;
|
||||
|
||||
/* If the revision has been previously detected,
|
||||
* just return it and don't do the whole detection stuff
|
||||
*/
|
||||
if (revision != HW_REV_NOT_DETECTED)
|
||||
return revision;
|
||||
|
||||
@@ -45,12 +48,15 @@ enum hw_revision get_pcb_hardware_version(void)
|
||||
HW_REV_DETECT_GPIO->PUPDR |= PULLUP(current_pin);
|
||||
}
|
||||
|
||||
/* Loop again and read in the pin mask */
|
||||
/* Loop again and read in the pin mask.
|
||||
* Because we use GND-Shorts on the pins to detect the version, the pins are read inverted.
|
||||
*/
|
||||
for (current_pin = HW_REV_DETECT_PIN_LOW; current_pin <= HW_REV_DETECT_PIN_HIGH; current_pin++) {
|
||||
port_bitmask >>= 1;
|
||||
port_bitmask |= (HW_REV_DETECT_GPIO->IDR & (1 << current_pin)) ? 0x0 : 0x80;
|
||||
}
|
||||
|
||||
/* Resolve the read in bitmask to a hardware version */
|
||||
switch (port_bitmask) {
|
||||
case 0U:
|
||||
revision = HW_REV_V1_2;
|
||||
@@ -58,6 +64,9 @@ enum hw_revision get_pcb_hardware_version(void)
|
||||
case 1U:
|
||||
revision = HW_REV_V1_3;
|
||||
break;
|
||||
case 2U:
|
||||
revision = HW_REV_V1_3_1;
|
||||
break;
|
||||
default:
|
||||
revision = HW_REV_ERROR;
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.14a /
|
||||
/ FatFs - Generic FAT Filesystem module R0.14b /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2020, ChaN, all right reserved.
|
||||
/ Copyright (C) 2021, 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 80196 /* Revision ID */
|
||||
#define FF_DEFINED 86631 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -35,10 +35,14 @@ extern "C" {
|
||||
|
||||
/* Integer types used for FatFs API */
|
||||
|
||||
#if defined(_WIN32) /* Main development platform */
|
||||
#if defined(_WIN32) /* Windows VC++ (for development only) */
|
||||
#define FF_INTDEF 2
|
||||
#include <windows.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
#include <float.h>
|
||||
#define isnan(v) _isnan(v)
|
||||
#define isinf(v) (!_finite(v))
|
||||
|
||||
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
|
||||
#define FF_INTDEF 2
|
||||
#include <stdint.h>
|
||||
@@ -48,6 +52,7 @@ typedef uint16_t WORD; /* 16-bit unsigned integer */
|
||||
typedef uint32_t DWORD; /* 32-bit unsigned integer */
|
||||
typedef uint64_t QWORD; /* 64-bit unsigned integer */
|
||||
typedef WORD WCHAR; /* UTF-16 character type */
|
||||
|
||||
#else /* Earlier than C99 */
|
||||
#define FF_INTDEF 1
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
@@ -58,28 +63,29 @@ typedef WORD WCHAR; /* UTF-16 character type */
|
||||
#endif
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
/* Type of file size and LBA variables */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition mapping table */
|
||||
#if FF_FS_EXFAT
|
||||
#if FF_INTDEF != 2
|
||||
#error exFAT feature wants C99 or later
|
||||
#endif
|
||||
|
||||
#if FF_STR_VOLUME_ID
|
||||
#ifndef FF_VOLUME_STRS
|
||||
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||
typedef QWORD FSIZE_t;
|
||||
#if FF_LBA64
|
||||
typedef QWORD LBA_t;
|
||||
#else
|
||||
typedef DWORD LBA_t;
|
||||
#endif
|
||||
#else
|
||||
#if FF_LBA64
|
||||
#error exFAT needs to be enabled when enable 64-bit LBA
|
||||
#endif
|
||||
typedef DWORD FSIZE_t;
|
||||
typedef DWORD LBA_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#ifndef _INC_TCHAR
|
||||
#define _INC_TCHAR
|
||||
/* Type of path name strings on FatFs API (TCHAR) */
|
||||
|
||||
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||
typedef WCHAR TCHAR;
|
||||
@@ -101,28 +107,22 @@ typedef char TCHAR;
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
/* Type of file size and LBA variables */
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition mapping table */
|
||||
#endif
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
#if FF_INTDEF != 2
|
||||
#error exFAT feature wants C99 or later
|
||||
#if FF_STR_VOLUME_ID
|
||||
#ifndef FF_VOLUME_STRS
|
||||
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||
#endif
|
||||
typedef QWORD FSIZE_t;
|
||||
#if FF_LBA64
|
||||
typedef QWORD LBA_t;
|
||||
#else
|
||||
typedef DWORD LBA_t;
|
||||
#endif
|
||||
#else
|
||||
#if FF_LBA64
|
||||
#error exFAT needs to be enabled when enable 64-bit LBA
|
||||
#endif
|
||||
typedef DWORD FSIZE_t;
|
||||
typedef DWORD LBA_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
/ FatFs Functional Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 80196 /* Revision ID */
|
||||
#define FFCONF_DEF 86631 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
@@ -25,14 +25,6 @@
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 1
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 1
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
@@ -64,6 +56,30 @@
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 1
|
||||
#define FF_PRINT_LLI 0
|
||||
#define FF_PRINT_FLOAT 0
|
||||
#define FF_STRF_ENCODE 0
|
||||
/* FF_USE_STRFUNC switches string functions, f_gets(), f_putc(), f_puts() and
|
||||
/ f_printf().
|
||||
/
|
||||
/ 0: Disable. FF_PRINT_LLI, FF_PRINT_FLOAT and FF_STRF_ENCODE have no effect.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 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.
|
||||
/ 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.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
@@ -137,19 +153,6 @@
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#define FF_STRF_ENCODE 3
|
||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
||||
/ This option selects assumption of character encoding ON THE FILE to be
|
||||
/ read/written via those functions.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 2
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
@@ -194,7 +197,7 @@
|
||||
#define FF_MAX_SS 512
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ harddisk, but a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
@@ -228,7 +231,7 @@
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 0
|
||||
#define FF_FS_EXFAT 1
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
@@ -65,11 +65,19 @@
|
||||
#define BEEPER_RCC_MASK RCC_AHB1ENR_GPIOBEN
|
||||
|
||||
/**
|
||||
* @brief Enable all clocks and setup pins in default setting
|
||||
* @brief Enable all clocks and setup pins in default setting.
|
||||
* @warning This function uses @ref rcc_manager_enable_clock to enable the clocks. Therefore, it must not be called
|
||||
* multiple times.
|
||||
* @note Calls @ref digio_set_default_values() internally.
|
||||
*/
|
||||
void digio_setup_default_all(void);
|
||||
void digio_init(void);
|
||||
|
||||
/**
|
||||
* @brief Setup or restore the default DIGIO settings.
|
||||
*
|
||||
* This function can be called multiple times.
|
||||
*/
|
||||
void digio_set_default_values(void);
|
||||
|
||||
/**
|
||||
* @brief Set up a DIGIO pin.
|
||||
|
@@ -57,6 +57,7 @@ enum hw_revision {
|
||||
HW_REV_ERROR = 1, /**< @brief The hardware revision could not be detected due to an internal error */
|
||||
HW_REV_V1_2 = 120, /**< @brief Hardware Revision v1.2 */
|
||||
HW_REV_V1_3 = 130, /**< @brief Hardware Revision v1.3 */
|
||||
HW_REV_V1_3_1 = 131, /**< @brief Hardware revision v1.3.1 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -70,6 +71,7 @@ enum hw_revision {
|
||||
* The function returns the HW revision as an enum hw_revision.
|
||||
* For v1.2 the return value is 120 (HW_REV_V1_2).
|
||||
* For v1.3 the return value is 130 (HW_REV_V1_3).
|
||||
* For v1.3.1 the return value is 131 (HW_REV_V1_3_1).
|
||||
*
|
||||
* Other return values are not defined yet.
|
||||
*
|
||||
|
@@ -25,9 +25,11 @@
|
||||
#endif
|
||||
|
||||
/* UART_DIV is 45.5625 => 115200 @ 84 MHz */
|
||||
#define SHELL_UART_DIV_FRACTION 9U /* Equals 9/16 = 0.5625 */
|
||||
#define SHELL_UART_DIV_MANTISSA 45U /* Equals 45 */
|
||||
#define SHELL_UART_DEFAULT_DIV_FRACTION 9U /* Equals 9/16 = 0.5625 */
|
||||
#define SHELL_UART_DEFAULT_DIV_MANTISSA 45U /* Equals 45 */
|
||||
|
||||
#define SHELL_UART_BRR_REG_VALUE ((SHELL_UART_DIV_MANTISSA<<4) | SHELL_UART_DIV_FRACTION);
|
||||
#define SHELL_UART_DEFAULT_BRR_REG_VALUE ((SHELL_UART_DEFAULT_DIV_MANTISSA<<4) | SHELL_UART_DEFAULT_DIV_FRACTION);
|
||||
|
||||
#define SHELL_UART_PERIPHERAL_CLOCK (84000000UL)
|
||||
|
||||
#endif /* __SHELL_UART_CONFIG_H__ */
|
||||
|
@@ -70,14 +70,14 @@ struct timing_monitor_info {
|
||||
* You have to call safety_controller_handle
|
||||
* If this function fails, it will hang, because errors in the safety controller are not recoverable
|
||||
*/
|
||||
void safety_controller_init();
|
||||
void safety_controller_init(void);
|
||||
|
||||
/**
|
||||
* @brief Handle the safety controller.
|
||||
* @note This function must be executed periodically in order to prevent the watchdog from resetting the firmware
|
||||
* @return 0 if successful
|
||||
*/
|
||||
int safety_controller_handle();
|
||||
int safety_controller_handle(void);
|
||||
|
||||
/**
|
||||
* @brief Report one or multiple errors to the safety controller
|
||||
@@ -170,13 +170,13 @@ bool safety_controller_get_flags_by_mask(enum safety_flag mask);
|
||||
* @brief Get the count of error flags
|
||||
* @return Error flag count
|
||||
*/
|
||||
uint32_t safety_controller_get_flag_count();
|
||||
uint32_t safety_controller_get_flag_count(void);
|
||||
|
||||
/**
|
||||
* @brief Get the count of analog monitors
|
||||
* @return Analog monitor count
|
||||
*/
|
||||
uint32_t safety_controller_get_analog_monitor_count();
|
||||
uint32_t safety_controller_get_analog_monitor_count(void);
|
||||
|
||||
/**
|
||||
* @brief Get an error flag's name by its index.
|
||||
|
@@ -28,12 +28,12 @@
|
||||
* @brief Initialize the SPI for the eeprom.
|
||||
* @return 0 if succesful
|
||||
*/
|
||||
int spi_eeprom_init();
|
||||
int spi_eeprom_init(void);
|
||||
|
||||
/**
|
||||
* @brief Uninitialize the SPI EEPROM
|
||||
*/
|
||||
void spi_eeprom_deinit();
|
||||
void spi_eeprom_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Read from SPI EEPROM
|
||||
|
@@ -25,7 +25,8 @@
|
||||
* @brief Convert PT1000 resistance to temperature in degrees celsius
|
||||
* @param resistance PT1000 resistance value
|
||||
* @param[out] temp_out Temperature output
|
||||
* @return 0 if ok, -1 if value is below conversion range, 1 if value is above conversion range,-1000 in case of pointer error
|
||||
* @return 0 if ok, -1 if value is below conversion range, 1 if value is above conversion range,
|
||||
* -1000 in case of pointer error
|
||||
*/
|
||||
int temp_converter_convert_resistance_to_temp(float resistance, float *temp_out);
|
||||
|
||||
|
@@ -44,9 +44,9 @@ enum tpe_status {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The current execution state of the temperature profile
|
||||
* @brief The execution state of the temperature profile
|
||||
*/
|
||||
struct tpe_current_state {
|
||||
struct tpe_exec_state {
|
||||
enum tpe_status status; /**< @brief Execution status */
|
||||
float setpoint; /**< @brief Temperature setpoint in degrees Celsius */
|
||||
uint64_t start_timestamp; /**< @brief The millisicend tick timestamp, the profile execution was started */
|
||||
@@ -78,7 +78,7 @@ int temp_profile_executer_handle(void);
|
||||
* @warning The returned state structure is static and used internally. You must not modify it.
|
||||
* @return Execution state
|
||||
*/
|
||||
const struct tpe_current_state *temp_profile_executer_status(void);
|
||||
const struct tpe_exec_state *temp_profile_executer_status(void);
|
||||
|
||||
/**
|
||||
* @brief Stop the temperature profile execution.
|
||||
|
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup temp-profile
|
||||
* @defgroup temp-profile Temperature Profile Parser and Executer
|
||||
* @{
|
||||
*/
|
||||
|
||||
@@ -41,6 +41,9 @@ enum pl_command_type {
|
||||
PL_LOUDSPEAKER_SET, /**< @brief Set the loudspeaker/beeper */
|
||||
PL_OFF, /**< @brief Disable the temperature output and shutdown the PID controller */
|
||||
PL_CLEAR_FLAGS, /**< @brief Try clear all flags */
|
||||
PL_DIGIO_CONF, /**< @brief Configure a DIGIO pin */
|
||||
PL_DIGIO_SET, /**< @brief Set a DIGIO pin */
|
||||
PL_DIGIO_WAIT, /**< @brief Wait until a DIGIO pin is set to the specified level */
|
||||
_PL_NUM_CMDS, /**< @brief Sentinel to determine the total amount of commands */
|
||||
};
|
||||
|
||||
@@ -56,7 +59,7 @@ enum pl_ret_val {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Maximum parameter count of a command
|
||||
* @brief Maximum parameter count of a command.
|
||||
*/
|
||||
#define PROFILE_LANG_MAX_NUM_ARGS (8)
|
||||
|
||||
@@ -89,7 +92,7 @@ enum pl_ret_val temp_profile_parse_from_file(const char *filename,
|
||||
uint32_t *cmds_parsed);
|
||||
|
||||
/**
|
||||
* @brief Fully free a comamnd list including hte sotred command structures.
|
||||
* @brief Fully free a comamnd list including hte stored command structures.
|
||||
*
|
||||
* \p list's destination is set to NULL to indicate the empty list.
|
||||
*
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#define _GUI_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* @brief Handle the reflow controller's LCD Menu
|
||||
@@ -29,10 +30,39 @@
|
||||
*/
|
||||
int gui_handle(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the GUI (LCD, button, and rotary encoder)
|
||||
*/
|
||||
void gui_init(void);
|
||||
|
||||
/**
|
||||
* @brief Set a overlay message displayed on top of the root menu
|
||||
* @param heading Heading of the overlay message (1st line)
|
||||
* @param text Text of the overlay (the two bottom lines, 2 times 16 chars)
|
||||
*/
|
||||
void gui_root_menu_message_set(const char *heading, const char *text);
|
||||
|
||||
/**
|
||||
* @brief Directly write to the LCD
|
||||
*
|
||||
* This function writes directly to the LCD and doesn't use the handling FSM in the
|
||||
* background. Therefore, the function will block until all data is written to the LCD.
|
||||
*
|
||||
* @param line line to write to. Starts at 0
|
||||
* @param text Text to write to the line
|
||||
*/
|
||||
void gui_lcd_write_direct_blocking(uint8_t line, const char *text);
|
||||
|
||||
/**
|
||||
* @brief Get the vertical size of the display
|
||||
* @return Count of rows
|
||||
*/
|
||||
size_t gui_get_line_count(void);
|
||||
|
||||
/**
|
||||
* @brief Return the const char disp[][21] array contianing all display rows
|
||||
* @note This directly returns the working buffer pointer. Do not change it!
|
||||
*/
|
||||
const char (*gui_get_current_display_content(void))[21];
|
||||
|
||||
#endif /* _GUI_H_ */
|
||||
|
51
stm-firmware/include/reflow-controller/ui/shell-uart.h
Normal file
51
stm-firmware/include/reflow-controller/ui/shell-uart.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2021 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 __SHELL_UART_H__
|
||||
|
||||
#include <shellmatta.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Configure the UART for the shellmatta shell.
|
||||
*
|
||||
* This will configure the UART for use with a DMA ring buffer.
|
||||
* @param uart
|
||||
*/
|
||||
void shell_uart_setup(void);
|
||||
|
||||
shellmatta_retCode_t shell_uart_write_callback(const char *data, uint32_t len);
|
||||
|
||||
int shell_uart_receive_data_with_dma(const char **data, size_t *len);
|
||||
|
||||
/**
|
||||
* @brief Configure a new connection speed.
|
||||
* @param new_baud Baudrate. E.g: 115200
|
||||
* @return Error in permille (1/1000). A return value of 2 means a baudrate error of: 0.002 or 0.2%.
|
||||
* Return value is negative in case of a hard error.
|
||||
*/
|
||||
int32_t shell_uart_reconfig_baud(uint32_t new_baud);
|
||||
|
||||
uint32_t shell_uart_get_current_baudrate(void);
|
||||
|
||||
#define __SHELL_UART_H__
|
||||
|
||||
#endif /* __SHELL_UART_H__ */
|
@@ -33,7 +33,7 @@ enum random_number_error {
|
||||
|
||||
void random_number_gen_init(bool int_enable);
|
||||
|
||||
void random_number_gen_deinit();
|
||||
void random_number_gen_deinit(void);
|
||||
|
||||
void random_number_gen_reset(bool int_en);
|
||||
|
||||
|
@@ -50,6 +50,8 @@ int uart_init(struct stm_uart *uart);
|
||||
|
||||
void uart_change_brr(struct stm_uart *uart, uint32_t brr);
|
||||
|
||||
uint32_t uart_get_brr(struct stm_uart *uart);
|
||||
|
||||
void uart_disable(struct stm_uart *uart);
|
||||
|
||||
void uart_send_char(struct stm_uart *uart, char c);
|
||||
|
@@ -33,4 +33,6 @@ void stm_unique_id_get(uint32_t *high, uint32_t *mid, uint32_t *low);
|
||||
|
||||
void stm_dev_rev_id_get(uint32_t *device_id, uint32_t *revision_id);
|
||||
|
||||
void stm_cpuid_get(uint8_t *implementer, uint8_t *variant, uint16_t *part_no, uint8_t *rev);
|
||||
|
||||
#endif /* __UNIQUE_ID_H__ */
|
||||
|
@@ -31,7 +31,6 @@
|
||||
#include <setup/system_stm32f4xx.h>
|
||||
#include <reflow-controller/systick.h>
|
||||
#include <reflow-controller/adc-meas.h>
|
||||
#include <reflow-controller/shell.h>
|
||||
#include <reflow-controller/digio.h>
|
||||
#include "fatfs/shimatta_sdio_driver/shimatta_sdio.h"
|
||||
#include <stm-periph/stm32-gpio-macros.h>
|
||||
@@ -41,6 +40,8 @@
|
||||
#include <reflow-controller/oven-driver.h>
|
||||
#include <fatfs/ff.h>
|
||||
#include <reflow-controller/ui/gui.h>
|
||||
#include <reflow-controller/ui/shell.h>
|
||||
#include <reflow-controller/ui/shell-uart.h>
|
||||
#include <reflow-controller/safety/safety-controller.h>
|
||||
#include <reflow-controller/settings/settings.h>
|
||||
#include <reflow-controller/safety/safety-memory.h>
|
||||
@@ -87,55 +88,6 @@ static inline void uart_gpio_config(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TX buffer for the shell's uart
|
||||
*/
|
||||
static char shell_uart_tx_buff[256];
|
||||
|
||||
/**
|
||||
* @brief RX buffer for the shell's uart
|
||||
*/
|
||||
static char shell_uart_rx_buff[48];
|
||||
|
||||
/**
|
||||
* @brief The uart instance handling the shellmatta shell.
|
||||
*/
|
||||
struct stm_uart shell_uart;
|
||||
|
||||
static shellmatta_retCode_t write_shell_callback(const char *data, uint32_t len)
|
||||
{
|
||||
uart_send_array_with_dma(&shell_uart, data, len);
|
||||
return SHELLMATTA_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the UART for the shellmatta shell.
|
||||
*
|
||||
* This will configure the UART for use with a DMA ring buffer.
|
||||
* @param uart
|
||||
*/
|
||||
static inline void setup_shell_uart(struct stm_uart *uart)
|
||||
{
|
||||
uart->rx = 1;
|
||||
uart->tx = 1;
|
||||
uart->brr_val = SHELL_UART_BRR_REG_VALUE;
|
||||
uart->rcc_reg = &SHELL_UART_RCC_REG;
|
||||
uart->rcc_bit_no = BITMASK_TO_BITNO(SHELL_UART_RCC_MASK);
|
||||
uart->uart_dev = SHELL_UART_PERIPH;
|
||||
uart->dma_rx_buff = shell_uart_rx_buff;
|
||||
uart->dma_tx_buff = shell_uart_tx_buff;
|
||||
uart->rx_buff_count = sizeof(shell_uart_rx_buff);
|
||||
uart->tx_buff_count = sizeof(shell_uart_tx_buff);
|
||||
uart->base_dma_num = 2;
|
||||
uart->dma_rx_stream = SHELL_UART_RECEIVE_DMA_STREAM;
|
||||
uart->dma_tx_stream = SHELL_UART_SEND_DMA_STREAM;
|
||||
uart->dma_rx_trigger_channel = SHELL_UART_RX_DMA_TRIGGER;
|
||||
uart->dma_tx_trigger_channel = SHELL_UART_TX_DMA_TRIGGER;
|
||||
|
||||
uart_init(uart);
|
||||
NVIC_EnableIRQ(DMA2_Stream7_IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mount the SD card if available and not already mounted
|
||||
* @param mounted The current mounting state of the SD card
|
||||
@@ -267,8 +219,8 @@ static inline void setup_system(void)
|
||||
/** - Initialize the oven output driver outputting the wavepacket control signal for the SSR and */
|
||||
oven_driver_init();
|
||||
|
||||
/** - Initialize all DIGIO Pins to theri default state and pin functions */
|
||||
digio_setup_default_all();
|
||||
/** - Initialize all DIGIO Pins to their default state and pin functions */
|
||||
digio_init();
|
||||
|
||||
/** - Set-up the LED outputs */
|
||||
led_setup();
|
||||
@@ -293,7 +245,7 @@ static inline void setup_system(void)
|
||||
handle_boot_status();
|
||||
|
||||
/** - Initialize the shell UART */
|
||||
setup_shell_uart(&shell_uart);
|
||||
shell_uart_setup();
|
||||
|
||||
/** - Enable the ADC for PT1000 measurement */
|
||||
adc_pt1000_setup_meas();
|
||||
@@ -314,7 +266,7 @@ static void handle_shell_uart_input(shellmatta_handle_t shell_handle)
|
||||
size_t uart_input_len;
|
||||
|
||||
/* Handle UART input for shell */
|
||||
uart_receive_status = uart_receive_data_with_dma(&shell_uart, &uart_input, &uart_input_len);
|
||||
uart_receive_status = shell_uart_receive_data_with_dma(&uart_input, &uart_input_len);
|
||||
if (uart_receive_status >= 0)
|
||||
shell_handle_input(shell_handle, uart_input, uart_input_len);
|
||||
}
|
||||
@@ -344,7 +296,7 @@ int main(void)
|
||||
adc_pt1000_set_resistance_calibration(offset, sens, true);
|
||||
|
||||
/** - Initialize the shellmatta shell */
|
||||
shell_handle = shell_init(write_shell_callback);
|
||||
shell_handle = shell_init(shell_uart_write_callback);
|
||||
|
||||
/** - Print motd to shell */
|
||||
shell_print_motd(shell_handle);
|
||||
@@ -421,16 +373,3 @@ void sdio_wait_ms(uint32_t ms)
|
||||
{
|
||||
systick_wait_ms(ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles the TX of UART1 (Shellmatta)
|
||||
*/
|
||||
void DMA2_Stream7_IRQHandler(void)
|
||||
{
|
||||
uint32_t hisr = DMA2->HISR & (0x3F << 22);
|
||||
|
||||
DMA2->HIFCR = hisr;
|
||||
|
||||
if (hisr & DMA_HISR_TCIF7)
|
||||
uart_tx_dma_complete_int_callback(&shell_uart);
|
||||
}
|
||||
|
@@ -41,12 +41,12 @@ static struct pid_controller IN_SECTION(.ccm.bss) oven_pid;
|
||||
/**
|
||||
* @brief Oven PID is currently running
|
||||
*/
|
||||
static bool oven_pid_running;
|
||||
static bool IN_SECTION(.ccm.bss) oven_pid_running;
|
||||
|
||||
/**
|
||||
* @brief Oven PID has been aborted / abnormally stopped.
|
||||
*/
|
||||
static bool oven_pid_aborted;
|
||||
static bool IN_SECTION(.ccm.bss) oven_pid_aborted;
|
||||
|
||||
/**
|
||||
* @brief Power level [0..100] of the oven to be applied
|
||||
|
@@ -78,5 +78,6 @@ void panic_mode(void)
|
||||
}
|
||||
|
||||
/* Let the watchdog do the rest */
|
||||
while (1);
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
@@ -1,22 +1,22 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup safety-adc
|
||||
@@ -31,8 +31,22 @@
|
||||
#include <reflow-controller/safety/safety-controller.h>
|
||||
|
||||
static const uint8_t safety_adc_channels[SAFETY_ADC_NUM_OF_CHANNELS] = {SAFETY_ADC_CHANNELS};
|
||||
static volatile uint8_t safety_adc_conversion_complete;
|
||||
static volatile uint8_t safety_adc_triggered;
|
||||
|
||||
/**
|
||||
* @brief Safety ADC conversion complete. Set in interrupt.
|
||||
*/
|
||||
static volatile uint8_t IN_SECTION(.ccm.bss) safety_adc_conversion_complete;
|
||||
|
||||
/**
|
||||
* @brief Safety ADC has been started. It will perform all specified conversions and
|
||||
* set @ref safety_adc_conversion_complete afterwards
|
||||
*/
|
||||
static volatile uint8_t IN_SECTION(.ccm.bss) safety_adc_triggered;
|
||||
|
||||
/**
|
||||
* @brief Safety ADC conversion storage. This is filled by DMA.
|
||||
* @note Do not move this to CCM RAM as the DMA won't be able to access it.
|
||||
*/
|
||||
static volatile uint16_t safety_adc_conversions[SAFETY_ADC_NUM_OF_CHANNELS];
|
||||
|
||||
void safety_adc_init(void)
|
||||
@@ -46,7 +60,8 @@ void safety_adc_init(void)
|
||||
rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(RCC_AHB1ENR_DMA2EN));
|
||||
|
||||
if (hw_rev != HW_REV_V1_2) {
|
||||
rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(SAFETY_ADC_SUPPLY_VOLTAGE_MONITOR_PORT_RCC_MASK));
|
||||
rcc_manager_enable_clock(&RCC->AHB1ENR,
|
||||
BITMASK_TO_BITNO(SAFETY_ADC_SUPPLY_VOLTAGE_MONITOR_PORT_RCC_MASK));
|
||||
SAFETY_ADC_SUPPLY_VOLTAGE_MONITOR_PORT->MODER &= MODER_DELETE(SAFETY_ADC_SUPPLY_VOLTAGE_MONITOR_PIN);
|
||||
SAFETY_ADC_SUPPLY_VOLTAGE_MONITOR_PORT->MODER |= ANALOG(SAFETY_ADC_SUPPLY_VOLTAGE_MONITOR_PIN);
|
||||
}
|
||||
@@ -58,7 +73,7 @@ void safety_adc_init(void)
|
||||
SAFETY_ADC_ADC_PERIPHERAL->SMPR1 |= ADC_SMPR1_SMP17 | ADC_SMPR1_SMP16 | ADC_SMPR1_SMP15;
|
||||
|
||||
/* Standard sequence. Measure all channels in one sequence */
|
||||
SAFETY_ADC_ADC_PERIPHERAL->SQR1 = (SAFETY_ADC_NUM_OF_CHANNELS - 1) << 20 ;
|
||||
SAFETY_ADC_ADC_PERIPHERAL->SQR1 = (SAFETY_ADC_NUM_OF_CHANNELS - 1) << 20;
|
||||
SAFETY_ADC_ADC_PERIPHERAL->SQR2 = 0UL;
|
||||
SAFETY_ADC_ADC_PERIPHERAL->SQR3 = 0UL;
|
||||
|
||||
@@ -83,7 +98,8 @@ void safety_adc_init(void)
|
||||
DMA2_Stream4->PAR = (uint32_t)&SAFETY_ADC_ADC_PERIPHERAL->DR;
|
||||
DMA2_Stream4->M0AR = (uint32_t)safety_adc_conversions;
|
||||
DMA2_Stream4->NDTR = SAFETY_ADC_NUM_OF_CHANNELS;
|
||||
DMA2_Stream4->CR = DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_CIRC | DMA_SxCR_TCIE | DMA_SxCR_EN;
|
||||
DMA2_Stream4->CR = DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_CIRC |
|
||||
DMA_SxCR_TCIE | DMA_SxCR_EN;
|
||||
NVIC_EnableIRQ(DMA2_Stream4_IRQn);
|
||||
|
||||
/* Enable ADC */
|
||||
@@ -161,7 +177,7 @@ void safety_adc_trigger_meas(void)
|
||||
safety_adc_triggered = 1;
|
||||
}
|
||||
|
||||
void DMA2_Stream4_IRQHandler()
|
||||
void DMA2_Stream4_IRQHandler(void)
|
||||
{
|
||||
uint32_t hisr;
|
||||
|
||||
|
@@ -1,22 +1,22 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup safety-controller
|
||||
@@ -215,8 +215,8 @@ static volatile struct error_flag IN_SECTION(.ccm.data) flags[] = {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief All timing monitors
|
||||
*/
|
||||
* @brief All timing monitors
|
||||
*/
|
||||
static volatile struct timing_mon IN_SECTION(.ccm.data) timings[] = {
|
||||
TIM_MON_ENTRY(ERR_TIMING_PID, 2, 5000, ERR_FLAG_TIMING_PID),
|
||||
TIM_MON_ENTRY(ERR_TIMING_MEAS_ADC, 0, 50, ERR_FLAG_TIMING_MEAS_ADC),
|
||||
@@ -298,7 +298,7 @@ static const struct crc_monitor_register meas_adc_crc_regs[] = {
|
||||
ADC_SQR2_SQ12 | ADC_SQR2_SQ11 | ADC_SQR2_SQ10 | ADC_SQR2_SQ9 |
|
||||
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),
|
||||
ADC_SQR3_SQ3 | ADC_SQR3_SQ2 | ADC_SQR3_SQ1, 4),
|
||||
{NULL, 0, 0}
|
||||
};
|
||||
|
||||
@@ -314,12 +314,11 @@ static const struct crc_monitor_register safety_adc_crc_regs[] = {
|
||||
ADC_SQR2_SQ12 | ADC_SQR2_SQ11 | ADC_SQR2_SQ10 | ADC_SQR2_SQ9 |
|
||||
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),
|
||||
ADC_SQR3_SQ3 | ADC_SQR3_SQ2 | ADC_SQR3_SQ1, 4),
|
||||
{NULL, 0, 0}
|
||||
};
|
||||
|
||||
static struct crc_mon IN_SECTION(.ccm.data) crc_monitors[] =
|
||||
{
|
||||
static struct crc_mon IN_SECTION(.ccm.data) crc_monitors[] = {
|
||||
{
|
||||
.registers = meas_adc_crc_regs,
|
||||
.monitor = ERR_CRC_MON_MEAS_ADC,
|
||||
@@ -360,7 +359,8 @@ static void set_overtemp_config(float over_temperature)
|
||||
safety_controller_overtemp_config.crc_dummy_seed = 0xA4F5C7E6UL;
|
||||
safety_controller_overtemp_config.overtemp_deg_celsius = over_temperature;
|
||||
safety_controller_overtemp_config.overtemp_equiv_resistance = resistance;
|
||||
crc_unit_input_array((const uint32_t *)&safety_controller_overtemp_config, wordsize_of(struct overtemp_config) - 1);
|
||||
crc_unit_input_array((const uint32_t *)&safety_controller_overtemp_config,
|
||||
wordsize_of(struct overtemp_config) - 1);
|
||||
safety_controller_overtemp_config.crc = crc_unit_get_crc();
|
||||
}
|
||||
|
||||
@@ -369,7 +369,8 @@ static bool over_temperature_config_check(void)
|
||||
if (safety_controller_overtemp_config.crc_dummy_seed != 0xA4F5C7E6UL)
|
||||
return true;
|
||||
crc_unit_reset();
|
||||
crc_unit_input_array((const uint32_t *)&safety_controller_overtemp_config, wordsize_of(struct overtemp_config) - 1);
|
||||
crc_unit_input_array((const uint32_t *)&safety_controller_overtemp_config,
|
||||
wordsize_of(struct overtemp_config) - 1);
|
||||
if (crc_unit_get_crc() != safety_controller_overtemp_config.crc)
|
||||
return true;
|
||||
|
||||
@@ -442,7 +443,7 @@ static int flag_weight_table_crc_check(void)
|
||||
static int flag_persistence_table_crc_check(void)
|
||||
{
|
||||
crc_unit_reset();
|
||||
crc_unit_input_array((uint32_t*)flag_persistencies, wordsize_of(flag_persistencies));
|
||||
crc_unit_input_array((uint32_t *)flag_persistencies, wordsize_of(flag_persistencies));
|
||||
|
||||
if (crc_unit_get_crc() != flag_persistencies_crc)
|
||||
return -1;
|
||||
@@ -519,9 +520,8 @@ static int safety_controller_check_crc_monitors(void)
|
||||
|
||||
if (crc_monitor_calculate_crc(mon->registers, &crc))
|
||||
return -1;
|
||||
if (mon->expected_crc != crc || ~mon->expected_crc_inv != crc) {
|
||||
if (mon->expected_crc != crc || ~mon->expected_crc_inv != crc)
|
||||
safety_controller_report_error(mon->flag_to_set);
|
||||
}
|
||||
mon->last_crc = crc;
|
||||
}
|
||||
|
||||
@@ -548,7 +548,7 @@ static void init_safety_flag_weight_table_from_default(void)
|
||||
}
|
||||
|
||||
crc_unit_reset();
|
||||
crc_unit_input_array((uint32_t*)flag_weights, wordsize_of(flag_weights));
|
||||
crc_unit_input_array((uint32_t *)flag_weights, wordsize_of(flag_weights));
|
||||
flag_weight_crc = crc_unit_get_crc();
|
||||
}
|
||||
|
||||
@@ -608,16 +608,14 @@ static void apply_config_overrides(void)
|
||||
case SAFETY_MEMORY_CONFIG_OVERRIDE_WEIGHT:
|
||||
flag_enum = flag_no_to_flag_enum(override.entry.weight_override.flag);
|
||||
flag = find_error_flag(flag_enum);
|
||||
if (flag && flag->weight) {
|
||||
if (flag && flag->weight)
|
||||
flag->weight->weight = override.entry.weight_override.weight;
|
||||
}
|
||||
break;
|
||||
case SAFETY_MEMORY_CONFIG_OVERRIDE_PERSISTENCE:
|
||||
flag_enum = flag_no_to_flag_enum(override.entry.persistence_override.flag);
|
||||
flag = find_error_flag(flag_enum);
|
||||
if (flag && flag->persistence) {
|
||||
if (flag && flag->persistence)
|
||||
flag->persistence->persistence = override.entry.persistence_override.persistence;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
@@ -629,7 +627,7 @@ static void apply_config_overrides(void)
|
||||
crc_unit_input_array((uint32_t *)flag_persistencies, wordsize_of(flag_persistencies));
|
||||
flag_persistencies_crc = crc_unit_get_crc();
|
||||
crc_unit_reset();
|
||||
crc_unit_input_array((uint32_t*)flag_weights, wordsize_of(flag_weights));
|
||||
crc_unit_input_array((uint32_t *)flag_weights, wordsize_of(flag_weights));
|
||||
flag_weight_crc = crc_unit_get_crc();
|
||||
}
|
||||
|
||||
@@ -647,11 +645,10 @@ static bool error_flag_get_status(const volatile struct error_flag *flag)
|
||||
if (!flag)
|
||||
return true;
|
||||
|
||||
if (flag->error_state == flag->error_state_inv) {
|
||||
if (flag->error_state == flag->error_state_inv)
|
||||
return true;
|
||||
} else {
|
||||
else
|
||||
return flag->error_state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -693,7 +690,7 @@ static volatile struct timing_mon *find_timing_mon(enum timing_monitor mon)
|
||||
/**
|
||||
* @brief Check the active timing monitors and set the appropriate flags in case of an error.
|
||||
*/
|
||||
static void safety_controller_process_active_timing_mons()
|
||||
static void safety_controller_process_active_timing_mons(void)
|
||||
{
|
||||
uint32_t i;
|
||||
volatile struct timing_mon *current_mon;
|
||||
@@ -716,7 +713,8 @@ static void safety_controller_process_active_timing_mons()
|
||||
* Process the analog and timing monitors and set the relevant flags in case of a monitor outside its limits.
|
||||
* Furthermore, the PT1000 resistance is checked for overtemperature
|
||||
*
|
||||
* The checking of the analog monitors will only be armed after a startup delay of 1000 ms to allow the values to stabilize.
|
||||
* The checking of the analog monitors will only be armed after a startup delay of 1000 ms to
|
||||
* allow the values to stabilize.
|
||||
*/
|
||||
static void safety_controller_process_monitor_checks(void)
|
||||
{
|
||||
@@ -731,21 +729,18 @@ static void safety_controller_process_monitor_checks(void)
|
||||
|
||||
if (startup_completed) {
|
||||
analog_mon_count = safety_controller_get_analog_monitor_count();
|
||||
for (idx = 0; idx < analog_mon_count; idx++) {
|
||||
for (idx = 0; idx < analog_mon_count; idx++)
|
||||
if (safety_controller_get_analog_mon_by_index(idx, &amon_info)) {
|
||||
panic_mode();
|
||||
}
|
||||
|
||||
if (amon_info.status != ANALOG_MONITOR_OK) {
|
||||
if (amon_info.status != ANALOG_MONITOR_OK)
|
||||
safety_controller_report_error(amon_info.associated_flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
adc_pt1000_get_current_resistance(&pt1000_val);
|
||||
if (pt1000_val > safety_controller_overtemp_config.overtemp_equiv_resistance) {
|
||||
if (pt1000_val > safety_controller_overtemp_config.overtemp_equiv_resistance)
|
||||
safety_controller_report_error(ERR_FLAG_OVERTEMP);
|
||||
}
|
||||
|
||||
(void)safety_controller_check_crc_monitors();
|
||||
|
||||
@@ -779,7 +774,7 @@ static int report_error(enum safety_flag flag, uint32_t key, bool prevent_error_
|
||||
flags[i].error_state_inv = !flags[i].error_state;
|
||||
flags[i].key = key;
|
||||
|
||||
if ((check_flag_persistent(&flags[i]) && !old_state && !prevent_error_mem_enty) ||
|
||||
if ((check_flag_persistent(&flags[i]) && !old_state && !prevent_error_mem_enty) ||
|
||||
get_flag_weight(&flags[i]) == SAFETY_FLAG_CONFIG_WEIGHT_PANIC) {
|
||||
err_mem_entry.counter = 1;
|
||||
err_mem_entry.flag_num = flag_enum_to_flag_no(flags[i].flag);
|
||||
@@ -820,9 +815,8 @@ void safety_controller_report_timing(enum timing_monitor monitor)
|
||||
tim = find_timing_mon(monitor);
|
||||
if (tim) {
|
||||
if (tim->enabled) {
|
||||
if (!systick_ticks_have_passed(tim->last, tim->min_delta) && tim->min_delta > 0U) {
|
||||
if (!systick_ticks_have_passed(tim->last, tim->min_delta) && tim->min_delta > 0U)
|
||||
safety_controller_report_error(tim->associated_flag);
|
||||
}
|
||||
}
|
||||
|
||||
tim->calculated_delta = timestamp - tim->last;
|
||||
@@ -870,9 +864,8 @@ static int get_safety_flags_from_error_mem(enum safety_flag *flags)
|
||||
|
||||
for (idx = 0; idx < count; idx++) {
|
||||
res = safety_memory_get_error_entry(idx, &entry);
|
||||
if (entry.type == SAFETY_MEMORY_ERR_ENTRY_FLAG) {
|
||||
if (entry.type == SAFETY_MEMORY_ERR_ENTRY_FLAG)
|
||||
return_flags |= flag_no_to_flag_enum(entry.flag_num);
|
||||
}
|
||||
}
|
||||
|
||||
*flags = return_flags;
|
||||
@@ -884,11 +877,12 @@ static int get_safety_flags_from_error_mem(enum safety_flag *flags)
|
||||
*
|
||||
* The external harware watchdog has to be periodically reset or it will reset hte controller.
|
||||
* Because debugging is not possible, when the watchdog is active, it is only activated, if the application is
|
||||
* compiled in release mode. Any interruption of the main programm will then trigger the internal and/or the external watchdog.
|
||||
* compiled in release mode. Any interruption of the main programm will then trigger the internal and/or
|
||||
* the external watchdog.
|
||||
*
|
||||
* @note When enabled, execute the @ref external_watchdog_toggle function to reset the external watchdog.
|
||||
*/
|
||||
static void safety_controller_init_external_watchdog()
|
||||
static void safety_controller_init_external_watchdog(void)
|
||||
{
|
||||
rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(SAFETY_EXT_WATCHDOG_RCC_MASK));
|
||||
SAFETY_EXT_WATCHDOG_PORT->MODER &= MODER_DELETE(SAFETY_EXT_WATCHDOG_PIN);
|
||||
@@ -899,7 +893,7 @@ static void safety_controller_init_external_watchdog()
|
||||
__DSB();
|
||||
}
|
||||
|
||||
void safety_controller_init()
|
||||
void safety_controller_init(void)
|
||||
{
|
||||
enum safety_memory_state found_memory_state;
|
||||
enum safety_flag flags_in_err_mem = ERR_FLAG_NO_FLAG;
|
||||
@@ -967,7 +961,7 @@ void safety_controller_init()
|
||||
* 1) Checking the remaining free space at the moment between stack pointer and top of heap.
|
||||
* 2) Checking The CRC of the corruption detect area between heap and stack
|
||||
*/
|
||||
static void safety_controller_check_stack()
|
||||
static void safety_controller_check_stack(void)
|
||||
{
|
||||
int32_t free_stack;
|
||||
|
||||
@@ -975,18 +969,17 @@ static void safety_controller_check_stack()
|
||||
if (free_stack < SAFETY_MIN_STACK_FREE)
|
||||
safety_controller_report_error(ERR_FLAG_STACK);
|
||||
|
||||
if (stack_check_corruption_detect_area()) {
|
||||
if (stack_check_corruption_detect_area())
|
||||
safety_controller_report_error(ERR_FLAG_STACK);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle the Safety ADC
|
||||
*
|
||||
* This function handles the safety ADC.
|
||||
* If the safety ADC ius not executing a measurment and the time since the last measurement has
|
||||
* passed @ref SAFETY_CONTROLLER_ADC_DELAY_MS, the safety ADC is retriggered and will automatically perform a measurement
|
||||
* on all of its channels.
|
||||
* If the safety ADC is not executing a measurment and the time since the last measurement has
|
||||
* passed @ref SAFETY_CONTROLLER_ADC_DELAY_MS, the safety ADC is retriggered and will automatically perform a
|
||||
* measurement on all of its channels.
|
||||
* When called again, this function will retrieve the data from the safety ADC and converts it into the
|
||||
* appropriate analog values for the analog value monitors.
|
||||
*
|
||||
@@ -995,7 +988,7 @@ static void safety_controller_check_stack()
|
||||
*
|
||||
* The channels, the ssafety ADC will convert is defined in its header file using the define @ref SAFETY_ADC_CHANNELS.
|
||||
*/
|
||||
static void safety_controller_handle_safety_adc()
|
||||
static void safety_controller_handle_safety_adc(void)
|
||||
{
|
||||
static uint64_t last_result_timestamp = 0;
|
||||
const uint16_t *channels;
|
||||
@@ -1066,9 +1059,8 @@ static void safety_controller_handle_memory_checks(void)
|
||||
/* Check the safety memory */
|
||||
if (safety_memory_check()) {
|
||||
(void)safety_memory_reinit(&found_state);
|
||||
if (found_state != SAFETY_MEMORY_INIT_VALID_MEMORY) {
|
||||
if (found_state != SAFETY_MEMORY_INIT_VALID_MEMORY)
|
||||
safety_controller_report_error(ERR_FLAG_SAFETY_MEM_CORRUPT);
|
||||
}
|
||||
}
|
||||
|
||||
/* If flag weight table is broken, reinit to default and set flag */
|
||||
@@ -1078,7 +1070,7 @@ static void safety_controller_handle_memory_checks(void)
|
||||
}
|
||||
|
||||
/* If persistence table is broken, reinit to default and set flag */
|
||||
if(flag_persistence_table_crc_check()) {
|
||||
if (flag_persistence_table_crc_check()) {
|
||||
safety_controller_report_error(ERR_FLAG_SAFETY_TAB_CORRUPT);
|
||||
init_safety_flag_persistencies_from_default();
|
||||
}
|
||||
@@ -1097,7 +1089,7 @@ static void safety_controller_handle_memory_checks(void)
|
||||
* If the systick stays constant for more than 1000 calls of this function,
|
||||
* the @ref ERR_FLAG_SYSTICK flag is set.
|
||||
*/
|
||||
static void safety_controller_do_systick_checking()
|
||||
static void safety_controller_do_systick_checking(void)
|
||||
{
|
||||
static uint64_t last_systick;
|
||||
static uint32_t same_systick_cnt = 0UL;
|
||||
@@ -1122,7 +1114,7 @@ static void safety_controller_do_systick_checking()
|
||||
* @note If no flag weigth is present for a given error flag, it is treated as the most critical category
|
||||
* (@ref SAFETY_FLAG_CONFIG_WEIGHT_PANIC)
|
||||
*/
|
||||
static void safety_controller_handle_weighted_flags()
|
||||
static void safety_controller_handle_weighted_flags(void)
|
||||
{
|
||||
uint32_t flag_index;
|
||||
volatile struct error_flag *current_flag;
|
||||
@@ -1132,9 +1124,8 @@ static void safety_controller_handle_weighted_flags()
|
||||
current_flag = &flags[flag_index];
|
||||
|
||||
/* Continue if this flag is not set */
|
||||
if (!error_flag_get_status(current_flag)) {
|
||||
if (!error_flag_get_status(current_flag))
|
||||
continue;
|
||||
}
|
||||
|
||||
flag_weigth = get_flag_weight(current_flag);
|
||||
switch (flag_weigth) {
|
||||
@@ -1155,13 +1146,13 @@ static void safety_controller_handle_weighted_flags()
|
||||
}
|
||||
|
||||
#ifndef DEBUGBUILD
|
||||
static void external_watchdog_toggle()
|
||||
static void external_watchdog_toggle(void)
|
||||
{
|
||||
SAFETY_EXT_WATCHDOG_PORT->ODR ^= (1<<SAFETY_EXT_WATCHDOG_PIN);
|
||||
}
|
||||
#endif
|
||||
|
||||
int safety_controller_handle()
|
||||
int safety_controller_handle(void)
|
||||
{
|
||||
int ret = 0;
|
||||
#ifndef DEBUGBUILD
|
||||
@@ -1273,9 +1264,8 @@ int safety_controller_ack_flag_with_key(enum safety_flag flag, uint32_t key)
|
||||
int ret = -1;
|
||||
volatile struct error_flag *found_flag;
|
||||
|
||||
if (!is_power_of_two(flag)) {
|
||||
if (!is_power_of_two(flag))
|
||||
return -1001;
|
||||
}
|
||||
|
||||
found_flag = find_error_flag(flag);
|
||||
if (found_flag) {
|
||||
@@ -1306,17 +1296,17 @@ bool safety_controller_get_flags_by_mask(enum safety_flag mask)
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t safety_controller_get_flag_count()
|
||||
uint32_t safety_controller_get_flag_count(void)
|
||||
{
|
||||
return COUNT_OF(flags);
|
||||
}
|
||||
|
||||
uint32_t safety_controller_get_analog_monitor_count()
|
||||
uint32_t safety_controller_get_analog_monitor_count(void)
|
||||
{
|
||||
return COUNT_OF(analog_mons);
|
||||
}
|
||||
|
||||
uint32_t safety_controller_get_timing_monitor_count()
|
||||
uint32_t safety_controller_get_timing_monitor_count(void)
|
||||
{
|
||||
return COUNT_OF(timings);
|
||||
}
|
||||
@@ -1423,9 +1413,8 @@ int safety_controller_get_timing_mon_by_index(uint32_t index, struct timing_moni
|
||||
if (!info)
|
||||
return -1002;
|
||||
|
||||
if (index >= COUNT_OF(timings)) {
|
||||
if (index >= COUNT_OF(timings))
|
||||
return -1001;
|
||||
}
|
||||
|
||||
mon = &timings[index];
|
||||
|
||||
@@ -1462,14 +1451,13 @@ extern const uint32_t __ld_sdata;
|
||||
extern const uint32_t __ld_edata;
|
||||
extern const uint32_t __ld_load_data;
|
||||
|
||||
int safety_controller_trigger_flash_crc_check()
|
||||
int safety_controller_trigger_flash_crc_check(void)
|
||||
{
|
||||
/* This structs needs to be volatile!!
|
||||
* This prevents the compiler form optimizing out the reads to the crcs which will be patched in later by
|
||||
* a separate python script!
|
||||
*/
|
||||
static volatile const struct flash_crcs IN_SECTION(.flashcrc) crcs_in_flash =
|
||||
{
|
||||
static volatile const struct flash_crcs IN_SECTION(.flashcrc) crcs_in_flash = {
|
||||
.start_magic = 0xA8BE53F9UL,
|
||||
.crc_section_ccm_data = 0UL,
|
||||
.crc_section_text = 0UL,
|
||||
@@ -1491,9 +1479,8 @@ int safety_controller_trigger_flash_crc_check()
|
||||
crc_unit_reset();
|
||||
crc_unit_input_array(&__ld_vectors_start, len);
|
||||
crc = crc_unit_get_crc();
|
||||
if (crc != crcs_in_flash.crc_section_vectors) {
|
||||
if (crc != crcs_in_flash.crc_section_vectors)
|
||||
safety_controller_report_error(ERR_FLAG_FLASH_CRC_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform CRC check over text section */
|
||||
@@ -1505,9 +1492,8 @@ int safety_controller_trigger_flash_crc_check()
|
||||
crc_unit_reset();
|
||||
crc_unit_input_array(&__ld_text_start, len);
|
||||
crc = crc_unit_get_crc();
|
||||
if (crc != crcs_in_flash.crc_section_text) {
|
||||
if (crc != crcs_in_flash.crc_section_text)
|
||||
safety_controller_report_error(ERR_FLAG_FLASH_CRC_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform CRC check over data section */
|
||||
@@ -1519,9 +1505,8 @@ int safety_controller_trigger_flash_crc_check()
|
||||
crc_unit_reset();
|
||||
crc_unit_input_array(&__ld_load_data, len);
|
||||
crc = crc_unit_get_crc();
|
||||
if (crc != crcs_in_flash.crc_section_data) {
|
||||
if (crc != crcs_in_flash.crc_section_data)
|
||||
safety_controller_report_error(ERR_FLAG_FLASH_CRC_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform CRC check over ccm data section */
|
||||
@@ -1533,9 +1518,8 @@ int safety_controller_trigger_flash_crc_check()
|
||||
crc_unit_reset();
|
||||
crc_unit_input_array(&__ld_load_ccm_data, len);
|
||||
crc = crc_unit_get_crc();
|
||||
if (crc != crcs_in_flash.crc_section_ccm_data) {
|
||||
if (crc != crcs_in_flash.crc_section_ccm_data)
|
||||
safety_controller_report_error(ERR_FLAG_FLASH_CRC_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
@@ -1,22 +1,22 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <reflow-controller/safety/safety-memory.h>
|
||||
#include <helper-macros/helper-macros.h>
|
||||
@@ -99,7 +99,8 @@ static enum safety_memory_state safety_memory_get_header(struct safety_memory_he
|
||||
res = 0;
|
||||
if (header->boot_status_offset < wordsize_of(struct safety_memory_header))
|
||||
res++;
|
||||
if (header->config_overrides_offset < header->boot_status_offset + wordsize_of(struct safety_memory_boot_status))
|
||||
if (header->config_overrides_offset < header->boot_status_offset +
|
||||
wordsize_of(struct safety_memory_boot_status))
|
||||
res++;
|
||||
if (header->config_overrides_len > SAFETY_MEMORY_CONFIG_OVERRIDE_COUNT)
|
||||
res++;
|
||||
@@ -107,7 +108,8 @@ static enum safety_memory_state safety_memory_get_header(struct safety_memory_he
|
||||
res++;
|
||||
if (header->err_memory_offset < header->firmware_update_filename + (SAFETY_MEMORY_UPDATE_FILENAME_MAXSIZE / 4))
|
||||
res++;
|
||||
if (header->err_memory_end >= backup_ram_get_size_in_words() || header->err_memory_end < header->err_memory_offset)
|
||||
if (header->err_memory_end >= backup_ram_get_size_in_words() ||
|
||||
header->err_memory_end < header->err_memory_offset)
|
||||
res++;
|
||||
|
||||
if (res) {
|
||||
@@ -148,7 +150,7 @@ static void safety_memory_write_new_header(void)
|
||||
safety_memory_write_and_patch_header(&header);
|
||||
}
|
||||
|
||||
static int safety_memory_check_crc()
|
||||
static int safety_memory_check_crc(void)
|
||||
{
|
||||
struct safety_memory_header header;
|
||||
enum safety_memory_state state = safety_memory_get_header(&header);
|
||||
@@ -181,7 +183,7 @@ static int safety_memory_check_crc()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int safety_memory_gen_crc()
|
||||
static int safety_memory_gen_crc(void)
|
||||
{
|
||||
struct safety_memory_header header;
|
||||
uint32_t word_addr;
|
||||
@@ -268,9 +270,8 @@ int safety_memory_get_boot_status(struct safety_memory_boot_status *status)
|
||||
if (!status)
|
||||
return -1001;
|
||||
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
|
||||
return -2000;
|
||||
}
|
||||
|
||||
if (safety_memory_check_crc())
|
||||
return -2001;
|
||||
@@ -289,9 +290,8 @@ int safety_memory_set_boot_status(const struct safety_memory_boot_status *status
|
||||
if (!status)
|
||||
return -1001;
|
||||
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
|
||||
return -2000;
|
||||
}
|
||||
|
||||
if (safety_memory_check_crc())
|
||||
return -2001;
|
||||
@@ -304,7 +304,7 @@ int safety_memory_set_boot_status(const struct safety_memory_boot_status *status
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int safety_memory_check_error_entries()
|
||||
static int safety_memory_check_error_entries(void)
|
||||
{
|
||||
struct safety_memory_header header;
|
||||
uint32_t addr;
|
||||
@@ -312,9 +312,8 @@ static int safety_memory_check_error_entries()
|
||||
int ret = 0;
|
||||
int res;
|
||||
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
|
||||
return -2000;
|
||||
}
|
||||
|
||||
for (addr = header.err_memory_offset; addr < header.err_memory_end; addr++) {
|
||||
res = backup_ram_get_data(addr, &data, 1UL);
|
||||
@@ -340,9 +339,8 @@ int safety_memory_get_error_entry_count(uint32_t *count)
|
||||
if (!count)
|
||||
return -1001;
|
||||
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
|
||||
return -2000;
|
||||
}
|
||||
|
||||
*count = header.err_memory_end - header.err_memory_offset;
|
||||
|
||||
@@ -354,9 +352,8 @@ int safety_memory_check(void)
|
||||
int res;
|
||||
|
||||
res = safety_memory_check_crc();
|
||||
if (!res) {
|
||||
if (!res)
|
||||
res |= safety_memory_check_error_entries();
|
||||
}
|
||||
|
||||
return -!!res;
|
||||
}
|
||||
@@ -372,9 +369,8 @@ int safety_memory_get_error_entry(uint32_t idx, struct error_memory_entry *entry
|
||||
if (!entry)
|
||||
return -1001;
|
||||
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
|
||||
return -2000;
|
||||
}
|
||||
|
||||
err_mem_count = header.err_memory_end - header.err_memory_offset;
|
||||
if (idx < err_mem_count && err_mem_count > 0) {
|
||||
@@ -410,9 +406,8 @@ int safety_memory_insert_error_entry(struct error_memory_entry *entry)
|
||||
|
||||
input_data = error_memory_entry_to_word(entry);
|
||||
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
|
||||
return -2000;
|
||||
}
|
||||
|
||||
if (entry->type == SAFETY_MEMORY_ERR_ENTRY_NOP) {
|
||||
/* Append to end */
|
||||
@@ -510,9 +505,8 @@ int safety_memory_insert_config_override(struct config_override *config_override
|
||||
int res;
|
||||
int ret = -3;
|
||||
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
|
||||
return -2000;
|
||||
}
|
||||
|
||||
if (header.config_overrides_len == 0)
|
||||
return -1;
|
||||
@@ -550,9 +544,8 @@ int safety_memory_get_config_override_count(uint32_t *count)
|
||||
|
||||
*count = 0UL;
|
||||
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
|
||||
return -2000;
|
||||
}
|
||||
|
||||
if (header.config_overrides_len == 0)
|
||||
return 0;
|
||||
@@ -582,18 +575,15 @@ int safety_memory_get_config_override(uint32_t idx, struct config_override *conf
|
||||
if (!config_override)
|
||||
return -1002;
|
||||
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
|
||||
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
|
||||
return -2000;
|
||||
}
|
||||
|
||||
if (idx >= header.config_overrides_len) {
|
||||
if (idx >= header.config_overrides_len)
|
||||
return -1001;
|
||||
}
|
||||
|
||||
res = backup_ram_get_data(header.config_overrides_offset + idx, &data, 1UL);
|
||||
if (res) {
|
||||
if (res)
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (data & 0xFF) {
|
||||
case 0xA2:
|
||||
@@ -649,8 +639,8 @@ int safety_memory_get_update_filename(char *filename, size_t *outlen)
|
||||
{
|
||||
struct safety_memory_header header;
|
||||
unsigned int i;
|
||||
volatile char *ptr;
|
||||
size_t len = 0u;
|
||||
volatile char *ptr;
|
||||
|
||||
/* If filename and outlen are both NULL, we don't do anything */
|
||||
if (!filename && !outlen)
|
||||
@@ -696,9 +686,9 @@ int safety_memory_set_update_filename(const char *filename)
|
||||
ram_ptr = backup_ram_get_base_ptr();
|
||||
ram_ptr += header.firmware_update_filename * 4;
|
||||
|
||||
for (i = 0u; i < len; i++) {
|
||||
for (i = 0u; i < len; i++)
|
||||
ram_ptr[i] = filename[i];
|
||||
}
|
||||
|
||||
ram_ptr[i] = 0;
|
||||
|
||||
ret = safety_memory_gen_crc();
|
||||
|
@@ -1,22 +1,22 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <reflow-controller/safety/stack-check.h>
|
||||
#include <stdint.h>
|
||||
@@ -26,7 +26,7 @@
|
||||
extern char __ld_top_of_stack;
|
||||
extern char __ld_end_stack;
|
||||
|
||||
int32_t stack_check_get_usage()
|
||||
int32_t stack_check_get_usage(void)
|
||||
{
|
||||
uint32_t stack_top;
|
||||
uint32_t stack_ptr;
|
||||
@@ -37,7 +37,7 @@ int32_t stack_check_get_usage()
|
||||
return stack_top - stack_ptr;
|
||||
}
|
||||
|
||||
int32_t stack_check_get_free()
|
||||
int32_t stack_check_get_free(void)
|
||||
{
|
||||
uint32_t upper_heap_boundary;
|
||||
uint32_t stack_ptr;
|
||||
@@ -102,9 +102,6 @@ int stack_check_corruption_detect_area(void)
|
||||
&__ld_start_stack_corruption_detect_area;
|
||||
crc_unit_reset();
|
||||
crc_unit_input_array(&__ld_start_stack_corruption_detect_area, area_size_in_words);
|
||||
if (crc_unit_get_crc() == 0UL) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return crc_unit_get_crc() == 0UL ? 0 : -1;
|
||||
}
|
||||
|
@@ -1,22 +1,22 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup watchdog
|
||||
@@ -50,7 +50,8 @@ int watchdog_setup(uint8_t prescaler)
|
||||
RCC->CSR |= RCC_CSR_LSION;
|
||||
__DSB();
|
||||
/** - Wait for the oscillator to be ready */
|
||||
while (!(RCC->CSR & RCC_CSR_LSIRDY));
|
||||
while (!(RCC->CSR & RCC_CSR_LSIRDY))
|
||||
;
|
||||
|
||||
if (prescaler == 4U)
|
||||
prescaler_reg_val = 0UL;
|
||||
@@ -67,17 +68,25 @@ int watchdog_setup(uint8_t prescaler)
|
||||
else
|
||||
prescaler_reg_val = 6UL;
|
||||
|
||||
/** - (De)activate the watchdog during debug access according to @ref WATCHDOG_HALT_DEBUG */
|
||||
if (WATCHDOG_HALT_DEBUG)
|
||||
DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_IWDG_STOP;
|
||||
else
|
||||
DBGMCU->APB1FZ &= ~DBGMCU_APB1_FZ_DBG_IWDG_STOP;
|
||||
|
||||
/** - Unlock registers */
|
||||
IWDG->KR = STM32_WATCHDOG_REGISTER_ACCESS_KEY;
|
||||
|
||||
/** - Wait until prescaler can be written */
|
||||
while (IWDG->SR & IWDG_SR_PVU);
|
||||
while (IWDG->SR & IWDG_SR_PVU)
|
||||
;
|
||||
|
||||
/** - Write prescaler value */
|
||||
IWDG->PR = prescaler_reg_val;
|
||||
|
||||
/* - Wait until reload value can be written */
|
||||
while (IWDG->SR & IWDG_SR_RVU);
|
||||
while (IWDG->SR & IWDG_SR_RVU)
|
||||
;
|
||||
|
||||
/** - Set reload value fixed to 0xFFF */
|
||||
IWDG->RLR = 0xFFFU;
|
||||
|
@@ -1,22 +1,22 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <reflow-controller/settings/settings-eeprom.h>
|
||||
#include <reflow-controller/settings/spi-eeprom.h>
|
||||
@@ -37,6 +37,7 @@ struct eeprom_calibration_settings {
|
||||
};
|
||||
|
||||
#define EEPROM_OVER_TEMP_CONFIG_BASE_ADDR (EEPROM_CALIBRATION_BASE_ADDR + sizeof(struct eeprom_calibration_settings))
|
||||
|
||||
struct eeprom_over_temp_config {
|
||||
float over_temperature;
|
||||
uint32_t over_temp_crc;
|
||||
@@ -54,15 +55,15 @@ static bool check_eeprom_header(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void settings_eeprom_zero()
|
||||
static void settings_eeprom_zero(void)
|
||||
{
|
||||
settings_eeprom_save_calibration(0.0f, 0.0f, false);
|
||||
settings_eeprom_save_overtemp_limit(0.0, false);
|
||||
settings_eeprom_save_overtemp_limit(0.0f, false);
|
||||
}
|
||||
|
||||
bool settings_eeprom_detect_and_prepare(void)
|
||||
{
|
||||
bool eeprom_ready = false;;
|
||||
bool eeprom_ready = false;
|
||||
|
||||
int res;
|
||||
|
||||
@@ -77,7 +78,10 @@ bool settings_eeprom_detect_and_prepare(void)
|
||||
if (check_eeprom_header() == false) {
|
||||
/* Try to write a new header and check it again */
|
||||
spi_eeprom_write(0, expected_header, sizeof(expected_header));
|
||||
while (spi_eeprom_write_in_progress());
|
||||
|
||||
while (spi_eeprom_write_in_progress())
|
||||
;
|
||||
|
||||
if (check_eeprom_header() == false) {
|
||||
goto ret_deinit_crc;
|
||||
} else {
|
||||
|
@@ -1,22 +1,22 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <reflow-controller/settings/settings-sd-card.h>
|
||||
#include <stm-periph/unique-id.h>
|
||||
@@ -72,18 +72,12 @@ static int create_controller_folder(void)
|
||||
ret = 0;
|
||||
} else {
|
||||
filesystem_result = f_mkdir(foldername);
|
||||
if (filesystem_result == FR_OK) {
|
||||
ret = 1;
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
ret = filesystem_result == FR_OK ? 1 : -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int sd_card_settings_save_calibration(float sens_deviation, float offset, bool active)
|
||||
{
|
||||
char path[200];
|
||||
|
@@ -1,22 +1,22 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <reflow-controller/settings/settings.h>
|
||||
#include <reflow-controller/settings/settings-sd-card.h>
|
||||
@@ -39,7 +39,7 @@ int settings_load_calibration(float *sens_dev, float *offset)
|
||||
int res;
|
||||
|
||||
if (settings_use_eeprom) {
|
||||
res =settings_eeprom_load_calibration(sens_dev, offset, &active);
|
||||
res = settings_eeprom_load_calibration(sens_dev, offset, &active);
|
||||
if (!res && !active)
|
||||
res = -1;
|
||||
} else {
|
||||
|
@@ -1,22 +1,22 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2021 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/>.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 2021 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/settings/spi-eeprom.h>
|
||||
#include <stm-periph/spi.h>
|
||||
@@ -52,7 +52,7 @@ static void eeprom_cs_deactivate(void)
|
||||
SPI_EEPROM_SPI_PORT->ODR |= (1<<SPI_EEPROM_CS_PIN);
|
||||
}
|
||||
|
||||
int spi_eeprom_init()
|
||||
int spi_eeprom_init(void)
|
||||
{
|
||||
static struct stm_spi_dev spi_dev;
|
||||
struct stm_spi_settings settings;
|
||||
@@ -61,7 +61,8 @@ int spi_eeprom_init()
|
||||
|
||||
SPI_EEPROM_SPI_PORT->MODER &= MODER_DELETE(SPI_EEPROM_CS_PIN) & MODER_DELETE(SPI_EEPROM_MISO_PIN) &
|
||||
MODER_DELETE(SPI_EEPROM_MOSI_PIN) & MODER_DELETE(SPI_EEPROM_SCK_PIN);
|
||||
SPI_EEPROM_SPI_PORT->MODER |= ALTFUNC(SPI_EEPROM_MISO_PIN) | ALTFUNC(SPI_EEPROM_SCK_PIN) | ALTFUNC(SPI_EEPROM_MOSI_PIN);
|
||||
SPI_EEPROM_SPI_PORT->MODER |= ALTFUNC(SPI_EEPROM_MISO_PIN) | ALTFUNC(SPI_EEPROM_SCK_PIN) |
|
||||
ALTFUNC(SPI_EEPROM_MOSI_PIN);
|
||||
SPI_EEPROM_SPI_PORT->MODER |= OUTPUT(SPI_EEPROM_CS_PIN);
|
||||
|
||||
SETAF(SPI_EEPROM_SPI_PORT, SPI_EEPROM_MISO_PIN, SPI_EEPROM_SPI_ALTFUNC_NO);
|
||||
@@ -85,7 +86,7 @@ int spi_eeprom_init()
|
||||
return -1;
|
||||
}
|
||||
|
||||
void spi_eeprom_deinit()
|
||||
void spi_eeprom_deinit(void)
|
||||
{
|
||||
spi_deinit(eeprom_spi_handle);
|
||||
|
||||
@@ -166,7 +167,8 @@ static void spi_eeprom_do_write_page(uint32_t addr, const uint8_t *data, uint8_t
|
||||
uint8_t cmd[2];
|
||||
|
||||
/* Wait for the previous write to finish */
|
||||
while (spi_eeprom_write_in_progress());
|
||||
while (spi_eeprom_write_in_progress())
|
||||
;
|
||||
/* Set the write enable latch */
|
||||
spi_eeprom_set_write_enable_latch(true);
|
||||
|
||||
|
@@ -46,7 +46,8 @@ void backup_ram_init(bool use_backup_regulator)
|
||||
PWR->CSR |= PWR_CSR_BRE;
|
||||
|
||||
/* Wait until regulator is ready */
|
||||
while (!(PWR->CSR & PWR_CSR_BRR));
|
||||
while (!(PWR->CSR & PWR_CSR_BRR))
|
||||
;
|
||||
}
|
||||
|
||||
/* Enable clock for backup ram interface */
|
||||
|
@@ -37,11 +37,10 @@ static size_t calculate_ring_buffer_fill_level(size_t buffer_size, size_t get_id
|
||||
{
|
||||
size_t fill_level;
|
||||
|
||||
if (put_idx >= get_idx) {
|
||||
if (put_idx >= get_idx)
|
||||
fill_level = (put_idx - get_idx);
|
||||
} else {
|
||||
else
|
||||
fill_level = buffer_size - get_idx + put_idx;
|
||||
}
|
||||
|
||||
return fill_level;
|
||||
}
|
||||
@@ -49,7 +48,7 @@ static size_t calculate_ring_buffer_fill_level(size_t buffer_size, size_t get_id
|
||||
static int dma_ring_buffer_switch_clock_enable(uint8_t base_dma, bool clk_en)
|
||||
{
|
||||
int ret_val;
|
||||
int (*clk_func)(volatile uint32_t *, uint8_t);
|
||||
int (*clk_func)(volatile uint32_t *reg, uint8_t bit_no);
|
||||
|
||||
if (clk_en)
|
||||
clk_func = rcc_manager_enable_clock;
|
||||
@@ -72,8 +71,9 @@ static int dma_ring_buffer_switch_clock_enable(uint8_t base_dma, bool clk_en)
|
||||
}
|
||||
|
||||
int dma_ring_buffer_periph_to_mem_initialize(struct dma_ring_buffer_to_mem *dma_buffer, uint8_t base_dma_id,
|
||||
DMA_Stream_TypeDef *dma_stream, size_t buffer_element_count, size_t element_size,
|
||||
volatile void *data_buffer, void* src_reg, uint8_t dma_trigger_channel)
|
||||
DMA_Stream_TypeDef *dma_stream, size_t buffer_element_count,
|
||||
size_t element_size, volatile void *data_buffer,
|
||||
void *src_reg, uint8_t dma_trigger_channel)
|
||||
{
|
||||
int ret_val = 0;
|
||||
|
||||
@@ -106,7 +106,8 @@ int dma_ring_buffer_periph_to_mem_initialize(struct dma_ring_buffer_to_mem *dma_
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dma_ring_buffer_periph_to_mem_get_data(struct dma_ring_buffer_to_mem *buff, const volatile void **data_buff, size_t *len)
|
||||
int dma_ring_buffer_periph_to_mem_get_data(struct dma_ring_buffer_to_mem *buff, const volatile void **data_buff,
|
||||
size_t *len)
|
||||
{
|
||||
int ret_code = 0;
|
||||
uint32_t ndtr;
|
||||
@@ -167,7 +168,10 @@ int dma_ring_buffer_periph_to_mem_fill_level(struct dma_ring_buffer_to_mem *buff
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dma_ring_buffer_mem_to_periph_initialize(struct dma_ring_buffer_to_periph *dma_buffer, uint8_t base_dma_id, DMA_Stream_TypeDef *dma_stream, size_t buffer_element_count, size_t element_size, volatile void *data_buffer, uint8_t dma_trigger_channel, void *dest_reg)
|
||||
int dma_ring_buffer_mem_to_periph_initialize(struct dma_ring_buffer_to_periph *dma_buffer, uint8_t base_dma_id,
|
||||
DMA_Stream_TypeDef *dma_stream, size_t buffer_element_count,
|
||||
size_t element_size, volatile void *data_buffer,
|
||||
uint8_t dma_trigger_channel, void *dest_reg)
|
||||
{
|
||||
if (!dma_buffer || !dma_stream || !data_buffer || !dest_reg)
|
||||
return -1000;
|
||||
@@ -221,7 +225,8 @@ static void queue_or_start_dma_transfer(struct dma_ring_buffer_to_periph *buff)
|
||||
buff->dma->CR |= DMA_SxCR_EN;
|
||||
}
|
||||
|
||||
int dma_ring_buffer_mem_to_periph_insert_data(struct dma_ring_buffer_to_periph *buff, const void *data_to_insert, size_t count)
|
||||
int dma_ring_buffer_mem_to_periph_insert_data(struct dma_ring_buffer_to_periph *buff, const void *data_to_insert,
|
||||
size_t count)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t free_item_count;
|
||||
@@ -234,7 +239,8 @@ int dma_ring_buffer_mem_to_periph_insert_data(struct dma_ring_buffer_to_periph *
|
||||
return -1000;
|
||||
|
||||
/* Check if data fits into buffer minus one element. If not: try full-1 buffer and rest
|
||||
* Buffer is not allowed to be completely full, because I cannot ddifferentiate a full buffer from a completely empty one
|
||||
* Buffer is not allowed to be completely full, because I cannot ddifferentiate a full buffer from a
|
||||
* completely empty one
|
||||
*/
|
||||
if (count >= buff->buffer_count) {
|
||||
ret = dma_ring_buffer_mem_to_periph_insert_data(buff, data_to_insert, buff->buffer_count - 1);
|
||||
@@ -247,7 +253,9 @@ int dma_ring_buffer_mem_to_periph_insert_data(struct dma_ring_buffer_to_periph *
|
||||
|
||||
/* Wait for buffer to be able to handle input */
|
||||
do {
|
||||
free_item_count = buff->buffer_count - calculate_ring_buffer_fill_level(buff->buffer_count, buff->dma_get_idx_current, buff->sw_put_idx);
|
||||
free_item_count = buff->buffer_count -
|
||||
calculate_ring_buffer_fill_level(buff->buffer_count, buff->dma_get_idx_current,
|
||||
buff->sw_put_idx);
|
||||
} while (free_item_count < count+1);
|
||||
|
||||
/* Fillup buffer (max is buffer end, wrap around afterwards) */
|
||||
@@ -261,7 +269,7 @@ int dma_ring_buffer_mem_to_periph_insert_data(struct dma_ring_buffer_to_periph *
|
||||
buff->sw_put_idx += count;
|
||||
|
||||
/* If buffer is used up to last element, set put index to beginning */
|
||||
if(buff->sw_put_idx >= buff->buffer_count)
|
||||
if (buff->sw_put_idx >= buff->buffer_count)
|
||||
buff->sw_put_idx = 0;
|
||||
} else {
|
||||
/* Fill up to end of buffer and fill rest after wrap around */
|
||||
|
@@ -76,12 +76,14 @@ int stm_option_bytes_program(const struct option_bytes *opts)
|
||||
reg |= (opts->read_protection << 8) & FLASH_OPTCR_RDP;
|
||||
reg |= (opts->wdg_sw << 5) & FLASH_OPTCR_WDG_SW;
|
||||
|
||||
while (FLASH->SR & FLASH_SR_BSY);
|
||||
while (FLASH->SR & FLASH_SR_BSY)
|
||||
;
|
||||
|
||||
FLASH->OPTCR = reg;
|
||||
FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT;
|
||||
__DSB();
|
||||
while (FLASH->SR & FLASH_SR_BSY);
|
||||
while (FLASH->SR & FLASH_SR_BSY)
|
||||
;
|
||||
|
||||
FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;
|
||||
|
||||
|
@@ -95,9 +95,8 @@ int rcc_manager_enable_clock(volatile uint32_t *rcc_enable_register, uint8_t bit
|
||||
int ret_val = 0;
|
||||
struct rcc_enable_count *entry;
|
||||
|
||||
if (!rcc_enable_register || bit_no > 31) {
|
||||
if (!rcc_enable_register || bit_no > 31)
|
||||
return -1000;
|
||||
}
|
||||
|
||||
/* Enable the clock in any case, no matter what follows */
|
||||
*rcc_enable_register |= (1U<<bit_no);
|
||||
@@ -132,9 +131,8 @@ int rcc_manager_disable_clock(volatile uint32_t *rcc_enable_register, uint8_t bi
|
||||
int ret_val = -1;
|
||||
struct rcc_enable_count *entry;
|
||||
|
||||
if (!rcc_enable_register || bit_no > 31) {
|
||||
if (!rcc_enable_register || bit_no > 31)
|
||||
return -1000;
|
||||
}
|
||||
|
||||
entry = search_enable_entry_in_list(rcc_enable_register, bit_no);
|
||||
|
||||
|
@@ -30,7 +30,7 @@ void random_number_gen_init(bool int_enable)
|
||||
random_number_gen_reset(int_enable);
|
||||
}
|
||||
|
||||
void random_number_gen_deinit()
|
||||
void random_number_gen_deinit(void)
|
||||
{
|
||||
RNG->CR = 0;
|
||||
__DSB();
|
||||
@@ -66,5 +66,5 @@ enum random_number_error random_number_gen_get_number(uint32_t *random_number, b
|
||||
*random_number = RNG->DR;
|
||||
|
||||
/* Return from function with proper status */
|
||||
return (value_ready ? RNG_ERROR_OK : RNG_ERROR_NOT_READY);
|
||||
return value_ready ? RNG_ERROR_OK : RNG_ERROR_NOT_READY;
|
||||
}
|
||||
|
@@ -1,22 +1,22 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2021 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/>.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 2021 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 <stm-periph/spi.h>
|
||||
#include <helper-macros/helper-macros.h>
|
||||
@@ -65,7 +65,8 @@ static struct stm_spi_dev *spi_handle_to_struct(stm_spi_handle handle)
|
||||
return dev;
|
||||
}
|
||||
|
||||
stm_spi_handle spi_init(struct stm_spi_dev *spi_dev_struct, SPI_TypeDef *spi_regs, const struct stm_spi_settings *settings)
|
||||
stm_spi_handle spi_init(struct stm_spi_dev *spi_dev_struct, SPI_TypeDef *spi_regs,
|
||||
const struct stm_spi_settings *settings)
|
||||
{
|
||||
stm_spi_handle ret_handle = NULL;
|
||||
uint32_t reg_val;
|
||||
@@ -131,10 +132,14 @@ void spi_deinit(stm_spi_handle handle)
|
||||
|
||||
static uint8_t transfer_byte(uint8_t byte, struct stm_spi_dev *dev)
|
||||
{
|
||||
while (dev->spi_regs->SR & SPI_SR_BSY);
|
||||
while (dev->spi_regs->SR & SPI_SR_BSY)
|
||||
;
|
||||
|
||||
dev->spi_regs->DR = (uint16_t)byte;
|
||||
__DSB();
|
||||
while((dev->spi_regs->SR & SPI_SR_BSY) || !(dev->spi_regs->SR & SPI_SR_TXE));
|
||||
|
||||
while ((dev->spi_regs->SR & SPI_SR_BSY) || !(dev->spi_regs->SR & SPI_SR_TXE))
|
||||
;
|
||||
|
||||
return (uint8_t)dev->spi_regs->DR;
|
||||
}
|
||||
|
@@ -1,216 +1,227 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stm-periph/uart.h>
|
||||
#include <stm32/stm32f4xx.h>
|
||||
#include <stm-periph/rcc-manager.h>
|
||||
#include <stm-periph/stm32-gpio-macros.h>
|
||||
#include <stm-periph/dma-ring-buffer.h>
|
||||
#include <string.h>
|
||||
|
||||
int uart_init(struct stm_uart *uart)
|
||||
{
|
||||
int ret_val = 0;
|
||||
uint32_t cr3 = 0;
|
||||
uint32_t cr1 = 0;
|
||||
|
||||
if (!uart)
|
||||
return -1000;
|
||||
|
||||
rcc_manager_enable_clock(uart->rcc_reg, uart->rcc_bit_no);
|
||||
|
||||
/* Reset all config regs */
|
||||
uart->uart_dev->CR1 = uart->uart_dev->CR2 = uart->uart_dev->CR3 = 0UL;
|
||||
|
||||
/* Set baud rate */
|
||||
uart->uart_dev->BRR = uart->brr_val;
|
||||
|
||||
/* If DMA buffers are present, configure for DMA use */
|
||||
if (uart->dma_rx_buff && uart->rx) {
|
||||
cr3 |= USART_CR3_DMAR;
|
||||
|
||||
ret_val = dma_ring_buffer_periph_to_mem_initialize(&uart->rx_ring_buff,
|
||||
uart->base_dma_num,
|
||||
uart->dma_rx_stream,
|
||||
uart->rx_buff_count,
|
||||
1U,
|
||||
uart->dma_rx_buff,
|
||||
(char *)&uart->uart_dev->DR,
|
||||
uart->dma_rx_trigger_channel);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
if (uart->dma_tx_buff && uart->tx) {
|
||||
ret_val = dma_ring_buffer_mem_to_periph_initialize(&uart->tx_ring_buff,
|
||||
uart->base_dma_num,
|
||||
uart->dma_tx_stream,
|
||||
uart->tx_buff_count,
|
||||
1U,
|
||||
uart->dma_tx_buff,
|
||||
uart->dma_tx_trigger_channel,
|
||||
(void *)&uart->uart_dev->DR);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
cr3 |= USART_CR3_DMAT;
|
||||
}
|
||||
uart->uart_dev->CR3 = cr3;
|
||||
|
||||
if (uart->tx)
|
||||
cr1 |= USART_CR1_TE;
|
||||
if (uart->rx)
|
||||
cr1 |= USART_CR1_RE;
|
||||
|
||||
/* Enable uart */
|
||||
cr1 |= USART_CR1_UE;
|
||||
uart->uart_dev->CR1 = cr1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uart_change_brr(struct stm_uart *uart, uint32_t brr)
|
||||
{
|
||||
if (!uart || !uart->uart_dev)
|
||||
return;
|
||||
|
||||
uart->brr_val = brr;
|
||||
uart->uart_dev->BRR = brr;
|
||||
}
|
||||
|
||||
void uart_disable(struct stm_uart *uart)
|
||||
{
|
||||
if (!uart)
|
||||
return;
|
||||
|
||||
uart->uart_dev->CR1 = 0;
|
||||
uart->uart_dev->CR2 = 0;
|
||||
uart->uart_dev->CR3 = 0;
|
||||
|
||||
if (uart->rx && uart->dma_rx_buff)
|
||||
dma_ring_buffer_periph_to_mem_stop(&uart->rx_ring_buff);
|
||||
|
||||
if (uart->dma_tx_buff && uart->tx)
|
||||
dma_ring_buffer_mem_to_periph_stop(&uart->tx_ring_buff);
|
||||
|
||||
rcc_manager_disable_clock(uart->rcc_reg, uart->rcc_bit_no);
|
||||
}
|
||||
|
||||
void uart_send_char(struct stm_uart *uart, char c)
|
||||
{
|
||||
if (!uart || !uart->uart_dev)
|
||||
return;
|
||||
|
||||
while(!(uart->uart_dev->SR & USART_SR_TXE));
|
||||
uart->uart_dev->DR = c;
|
||||
}
|
||||
|
||||
void uart_send_array(struct stm_uart *uart, const char *data, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
uart_send_char(uart, data[i]);
|
||||
}
|
||||
|
||||
void uart_send_string(struct stm_uart *uart, const char *string)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; string[i] != '\0'; i++)
|
||||
uart_send_char(uart, string[i]);
|
||||
}
|
||||
|
||||
void uart_send_array_with_dma(struct stm_uart *uart, const char *data, uint32_t len)
|
||||
{
|
||||
if (!uart || !uart->dma_tx_buff)
|
||||
return;
|
||||
|
||||
dma_ring_buffer_mem_to_periph_insert_data(&uart->tx_ring_buff, data, len);
|
||||
}
|
||||
|
||||
void uart_send_string_with_dma(struct stm_uart *uart, const char *string)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = strlen(string);
|
||||
uart_send_array_with_dma(uart, string, (uint32_t)len);
|
||||
}
|
||||
|
||||
int uart_receive_data_with_dma(struct stm_uart *uart, const char **data, size_t *len)
|
||||
{
|
||||
if (!uart)
|
||||
return -1000;
|
||||
|
||||
return dma_ring_buffer_periph_to_mem_get_data(&uart->rx_ring_buff, (const volatile void **)data, len);
|
||||
}
|
||||
|
||||
char uart_get_char(struct stm_uart *uart)
|
||||
{
|
||||
if (!uart)
|
||||
return 0;
|
||||
/* Wait for data to be available */
|
||||
while (!(uart->uart_dev->SR & USART_SR_RXNE));
|
||||
|
||||
return (char)uart->uart_dev->DR;
|
||||
}
|
||||
|
||||
int uart_check_rx_avail(struct stm_uart *uart)
|
||||
{
|
||||
if (!uart)
|
||||
return 0;
|
||||
|
||||
if (uart->uart_dev->SR & USART_SR_RXNE)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uart_tx_dma_complete_int_callback(struct stm_uart *uart)
|
||||
{
|
||||
if (!uart)
|
||||
return;
|
||||
|
||||
dma_ring_buffer_mem_to_periph_int_callback(&uart->tx_ring_buff);
|
||||
}
|
||||
|
||||
size_t uart_dma_tx_queue_avail(struct stm_uart *uart)
|
||||
{
|
||||
size_t fill_level = 0UL;
|
||||
|
||||
if (!uart)
|
||||
return 0UL;
|
||||
|
||||
(void)dma_ring_buffer_mem_to_periph_fill_level(&uart->tx_ring_buff, &fill_level);
|
||||
|
||||
return fill_level;
|
||||
}
|
||||
|
||||
size_t uart_dma_rx_queue_avail(struct stm_uart *uart)
|
||||
{
|
||||
size_t fill_level = 0UL;
|
||||
|
||||
if (!uart)
|
||||
return 0UL;
|
||||
|
||||
(void)dma_ring_buffer_periph_to_mem_fill_level(&uart->rx_ring_buff, &fill_level);
|
||||
|
||||
return fill_level;
|
||||
}
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||
*
|
||||
* This file is part of the Reflow Oven Controller Project.
|
||||
*
|
||||
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the reflow oven controller project.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stm-periph/uart.h>
|
||||
#include <stm32/stm32f4xx.h>
|
||||
#include <stm-periph/rcc-manager.h>
|
||||
#include <stm-periph/stm32-gpio-macros.h>
|
||||
#include <stm-periph/dma-ring-buffer.h>
|
||||
#include <string.h>
|
||||
|
||||
int uart_init(struct stm_uart *uart)
|
||||
{
|
||||
int ret_val = 0;
|
||||
uint32_t cr3 = 0;
|
||||
uint32_t cr1 = 0;
|
||||
|
||||
if (!uart)
|
||||
return -1000;
|
||||
|
||||
rcc_manager_enable_clock(uart->rcc_reg, uart->rcc_bit_no);
|
||||
|
||||
/* Reset all config regs */
|
||||
uart->uart_dev->CR1 = uart->uart_dev->CR2 = uart->uart_dev->CR3 = 0UL;
|
||||
|
||||
/* Set baud rate */
|
||||
uart->uart_dev->BRR = uart->brr_val;
|
||||
|
||||
/* If DMA buffers are present, configure for DMA use */
|
||||
if (uart->dma_rx_buff && uart->rx) {
|
||||
cr3 |= USART_CR3_DMAR;
|
||||
|
||||
ret_val = dma_ring_buffer_periph_to_mem_initialize(&uart->rx_ring_buff,
|
||||
uart->base_dma_num,
|
||||
uart->dma_rx_stream,
|
||||
uart->rx_buff_count,
|
||||
1U,
|
||||
uart->dma_rx_buff,
|
||||
(char *)&uart->uart_dev->DR,
|
||||
uart->dma_rx_trigger_channel);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
if (uart->dma_tx_buff && uart->tx) {
|
||||
ret_val = dma_ring_buffer_mem_to_periph_initialize(&uart->tx_ring_buff,
|
||||
uart->base_dma_num,
|
||||
uart->dma_tx_stream,
|
||||
uart->tx_buff_count,
|
||||
1U,
|
||||
uart->dma_tx_buff,
|
||||
uart->dma_tx_trigger_channel,
|
||||
(void *)&uart->uart_dev->DR);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
cr3 |= USART_CR3_DMAT;
|
||||
}
|
||||
uart->uart_dev->CR3 = cr3;
|
||||
|
||||
if (uart->tx)
|
||||
cr1 |= USART_CR1_TE;
|
||||
if (uart->rx)
|
||||
cr1 |= USART_CR1_RE;
|
||||
|
||||
/* Enable uart */
|
||||
cr1 |= USART_CR1_UE;
|
||||
uart->uart_dev->CR1 = cr1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uart_change_brr(struct stm_uart *uart, uint32_t brr)
|
||||
{
|
||||
if (!uart || !uart->uart_dev)
|
||||
return;
|
||||
|
||||
uart->brr_val = brr;
|
||||
uart->uart_dev->BRR = brr;
|
||||
}
|
||||
|
||||
uint32_t uart_get_brr(struct stm_uart *uart)
|
||||
{
|
||||
if (!uart || !uart->uart_dev)
|
||||
return 0;
|
||||
|
||||
return uart->brr_val;
|
||||
}
|
||||
|
||||
void uart_disable(struct stm_uart *uart)
|
||||
{
|
||||
if (!uart)
|
||||
return;
|
||||
|
||||
uart->uart_dev->CR1 = 0;
|
||||
uart->uart_dev->CR2 = 0;
|
||||
uart->uart_dev->CR3 = 0;
|
||||
|
||||
if (uart->rx && uart->dma_rx_buff)
|
||||
dma_ring_buffer_periph_to_mem_stop(&uart->rx_ring_buff);
|
||||
|
||||
if (uart->dma_tx_buff && uart->tx)
|
||||
dma_ring_buffer_mem_to_periph_stop(&uart->tx_ring_buff);
|
||||
|
||||
rcc_manager_disable_clock(uart->rcc_reg, uart->rcc_bit_no);
|
||||
}
|
||||
|
||||
void uart_send_char(struct stm_uart *uart, char c)
|
||||
{
|
||||
if (!uart || !uart->uart_dev)
|
||||
return;
|
||||
|
||||
while (!(uart->uart_dev->SR & USART_SR_TXE))
|
||||
;
|
||||
|
||||
uart->uart_dev->DR = c;
|
||||
}
|
||||
|
||||
void uart_send_array(struct stm_uart *uart, const char *data, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
uart_send_char(uart, data[i]);
|
||||
}
|
||||
|
||||
void uart_send_string(struct stm_uart *uart, const char *string)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; string[i] != '\0'; i++)
|
||||
uart_send_char(uart, string[i]);
|
||||
}
|
||||
|
||||
void uart_send_array_with_dma(struct stm_uart *uart, const char *data, uint32_t len)
|
||||
{
|
||||
if (!uart || !uart->dma_tx_buff)
|
||||
return;
|
||||
|
||||
dma_ring_buffer_mem_to_periph_insert_data(&uart->tx_ring_buff, data, len);
|
||||
}
|
||||
|
||||
void uart_send_string_with_dma(struct stm_uart *uart, const char *string)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = strlen(string);
|
||||
uart_send_array_with_dma(uart, string, (uint32_t)len);
|
||||
}
|
||||
|
||||
int uart_receive_data_with_dma(struct stm_uart *uart, const char **data, size_t *len)
|
||||
{
|
||||
if (!uart)
|
||||
return -1000;
|
||||
|
||||
return dma_ring_buffer_periph_to_mem_get_data(&uart->rx_ring_buff, (const volatile void **)data, len);
|
||||
}
|
||||
|
||||
char uart_get_char(struct stm_uart *uart)
|
||||
{
|
||||
if (!uart)
|
||||
return 0;
|
||||
/* Wait for data to be available */
|
||||
while (!(uart->uart_dev->SR & USART_SR_RXNE))
|
||||
;
|
||||
|
||||
return (char)uart->uart_dev->DR;
|
||||
}
|
||||
|
||||
int uart_check_rx_avail(struct stm_uart *uart)
|
||||
{
|
||||
if (!uart)
|
||||
return 0;
|
||||
|
||||
if (uart->uart_dev->SR & USART_SR_RXNE)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uart_tx_dma_complete_int_callback(struct stm_uart *uart)
|
||||
{
|
||||
if (!uart)
|
||||
return;
|
||||
|
||||
dma_ring_buffer_mem_to_periph_int_callback(&uart->tx_ring_buff);
|
||||
}
|
||||
|
||||
size_t uart_dma_tx_queue_avail(struct stm_uart *uart)
|
||||
{
|
||||
size_t fill_level = 0UL;
|
||||
|
||||
if (!uart)
|
||||
return 0UL;
|
||||
|
||||
(void)dma_ring_buffer_mem_to_periph_fill_level(&uart->tx_ring_buff, &fill_level);
|
||||
|
||||
return fill_level;
|
||||
}
|
||||
|
||||
size_t uart_dma_rx_queue_avail(struct stm_uart *uart)
|
||||
{
|
||||
size_t fill_level = 0UL;
|
||||
|
||||
if (!uart)
|
||||
return 0UL;
|
||||
|
||||
(void)dma_ring_buffer_periph_to_mem_fill_level(&uart->rx_ring_buff, &fill_level);
|
||||
|
||||
return fill_level;
|
||||
}
|
||||
|
@@ -43,3 +43,23 @@ void stm_dev_rev_id_get(uint32_t *device_id, uint32_t *revision_id)
|
||||
if (revision_id)
|
||||
*revision_id = (DBGMCU->IDCODE & DBGMCU_IDCODE_REV_ID) >> 16;
|
||||
}
|
||||
|
||||
void stm_cpuid_get(uint8_t *implementer, uint8_t *variant, uint16_t *part_no, uint8_t *rev)
|
||||
{
|
||||
uint32_t cpuid;
|
||||
|
||||
cpuid = SCB->CPUID;
|
||||
|
||||
if (implementer)
|
||||
*implementer = (uint8_t)((cpuid >> 24) & 0xFFU);
|
||||
|
||||
if (variant)
|
||||
*variant = (uint8_t)((cpuid >> 20) & 0x0FU);
|
||||
|
||||
if (part_no)
|
||||
*part_no = (uint16_t)((cpuid >> 4) & 0x0FFFU);
|
||||
|
||||
if (rev)
|
||||
*rev = (uint8_t)(cpuid & 0x0FU);
|
||||
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@
|
||||
|
||||
#include <reflow-controller/safety/safety-controller.h>
|
||||
|
||||
static struct tpe_current_state IN_SECTION(.ccm.data) state = {
|
||||
static struct tpe_exec_state IN_SECTION(.ccm.data) current_state = {
|
||||
.status = TPE_OFF,
|
||||
.start_timestamp = 0,
|
||||
};
|
||||
@@ -46,7 +46,7 @@ static SlList *command_list = NULL;
|
||||
static void tpe_abort(void)
|
||||
{
|
||||
temp_profile_executer_stop();
|
||||
state.status = TPE_ABORT;
|
||||
current_state.status = TPE_ABORT;
|
||||
}
|
||||
|
||||
enum pl_ret_val temp_profile_executer_start(const char *filename)
|
||||
@@ -54,16 +54,16 @@ enum pl_ret_val temp_profile_executer_start(const char *filename)
|
||||
uint32_t parsed_count = 0;
|
||||
enum pl_ret_val res;
|
||||
|
||||
state.setpoint = 0.0f;
|
||||
state.start_timestamp = 0ULL;
|
||||
state.setpoint = 0.0f;
|
||||
state.step = 0;
|
||||
state.profile_steps = 0;
|
||||
current_state.setpoint = 0.0f;
|
||||
current_state.start_timestamp = 0ULL;
|
||||
current_state.setpoint = 0.0f;
|
||||
current_state.step = 0;
|
||||
current_state.profile_steps = 0;
|
||||
|
||||
oven_pid_stop();
|
||||
pid_should_run = false;
|
||||
state.status = TPE_OFF;
|
||||
state.profile_steps = 0;
|
||||
current_state.status = TPE_OFF;
|
||||
current_state.profile_steps = 0;
|
||||
cmd_continue = false;
|
||||
|
||||
/* This should never happen... But who knows */
|
||||
@@ -73,9 +73,9 @@ enum pl_ret_val temp_profile_executer_start(const char *filename)
|
||||
|
||||
res = temp_profile_parse_from_file(filename, &command_list, MAX_PROFILE_LENGTH, &parsed_count);
|
||||
if (res == PL_RET_SUCCESS) {
|
||||
state.profile_steps = parsed_count;
|
||||
state.status = TPE_RUNNING;
|
||||
state.start_timestamp = systick_get_global_tick();
|
||||
current_state.profile_steps = parsed_count;
|
||||
current_state.status = TPE_RUNNING;
|
||||
current_state.start_timestamp = systick_get_global_tick();
|
||||
} else {
|
||||
if (command_list)
|
||||
temp_profile_free_command_list(&command_list);
|
||||
@@ -132,7 +132,7 @@ static bool cmd_set_temp(struct pl_command *cmd)
|
||||
{
|
||||
reactivate_pid_if_suspended();
|
||||
oven_pid_set_target_temperature(cmd->params[0]);
|
||||
state.setpoint = cmd->params[0];
|
||||
current_state.setpoint = cmd->params[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -146,21 +146,21 @@ static bool cmd_ramp(struct pl_command *cmd, bool cmd_continue)
|
||||
|
||||
if (!cmd_continue) {
|
||||
/* Init of command */
|
||||
start_temp = state.setpoint;
|
||||
start_temp = current_state.setpoint;
|
||||
slope = (cmd->params[0] - start_temp) / cmd->params[1];
|
||||
reactivate_pid_if_suspended();
|
||||
oven_pid_set_target_temperature(start_temp);
|
||||
start_timestamp = systick_get_global_tick();
|
||||
} else {
|
||||
secs_passed = ((float)(systick_get_global_tick() - start_timestamp)) / 1000.0f;
|
||||
if ((state.setpoint <= cmd->params[0] && start_temp < cmd->params[0]) ||
|
||||
(state.setpoint >= cmd->params[0] && start_temp > cmd->params[0])) {
|
||||
state.setpoint = start_temp + secs_passed * slope;
|
||||
if ((current_state.setpoint <= cmd->params[0] && start_temp < cmd->params[0]) ||
|
||||
(current_state.setpoint >= cmd->params[0] && start_temp > cmd->params[0])) {
|
||||
current_state.setpoint = start_temp + secs_passed * slope;
|
||||
} else {
|
||||
state.setpoint = cmd->params[0];
|
||||
current_state.setpoint = cmd->params[0];
|
||||
ret = true;
|
||||
}
|
||||
oven_pid_set_target_temperature(state.setpoint);
|
||||
oven_pid_set_target_temperature(current_state.setpoint);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -185,6 +185,36 @@ static void cmd_ack_flags(void)
|
||||
|
||||
}
|
||||
|
||||
static void cmd_digio_conf(uint8_t digio_num, uint8_t mode)
|
||||
{
|
||||
uint8_t pin_mode;
|
||||
uint8_t alt_func = 0;
|
||||
|
||||
if (mode == 0 || mode == 1) {
|
||||
pin_mode = mode;
|
||||
} else if (mode >= 0x80 && mode <= 0x87) {
|
||||
/* Alternate function */
|
||||
pin_mode = 2;
|
||||
alt_func = mode - 0x80;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
digio_setup_pin(digio_num, pin_mode, alt_func);
|
||||
}
|
||||
|
||||
bool cmd_digio_wait(uint8_t digio_num, uint8_t digio_state)
|
||||
{
|
||||
bool advance = false;
|
||||
int res;
|
||||
|
||||
res = digio_get(digio_num);
|
||||
if (res < 0 || (uint8_t)res == digio_state)
|
||||
advance = true;
|
||||
|
||||
return advance;
|
||||
}
|
||||
|
||||
int temp_profile_executer_handle(void)
|
||||
{
|
||||
struct pl_command *current_cmd;
|
||||
@@ -195,7 +225,7 @@ int temp_profile_executer_handle(void)
|
||||
|
||||
|
||||
/* Return if no profile is currently executed */
|
||||
if (state.status != TPE_RUNNING)
|
||||
if (current_state.status != TPE_RUNNING)
|
||||
return -1;
|
||||
|
||||
/* Abort profile execution if oven PID is aborted. This is most likely due to some error flags */
|
||||
@@ -209,8 +239,8 @@ int temp_profile_executer_handle(void)
|
||||
if (!systick_ticks_have_passed(last_tick, 100))
|
||||
return 0;
|
||||
|
||||
current_cmd = (struct pl_command *)sl_list_nth(command_list, state.step)->data;
|
||||
next_step = state.step;
|
||||
current_cmd = (struct pl_command *)sl_list_nth(command_list, current_state.step)->data;
|
||||
next_step = current_state.step;
|
||||
|
||||
switch (current_cmd->cmd) {
|
||||
case PL_WAIT_FOR_TIME:
|
||||
@@ -250,6 +280,17 @@ int temp_profile_executer_handle(void)
|
||||
cmd_ack_flags();
|
||||
advance = true;
|
||||
break;
|
||||
case PL_DIGIO_CONF:
|
||||
advance = true;
|
||||
cmd_digio_conf((uint8_t)current_cmd->params[0], (uint8_t)current_cmd->params[1]);
|
||||
break;
|
||||
case PL_DIGIO_SET:
|
||||
digio_set((uint8_t)current_cmd->params[0], current_cmd->params[1] ? 1u : 0u);
|
||||
advance = true;
|
||||
break;
|
||||
case PL_DIGIO_WAIT:
|
||||
advance = cmd_digio_wait((uint8_t)current_cmd->params[0], current_cmd->params[1] ? 1u : 0u);
|
||||
break;
|
||||
default:
|
||||
tpe_abort();
|
||||
advance = true;
|
||||
@@ -259,9 +300,9 @@ int temp_profile_executer_handle(void)
|
||||
if (advance)
|
||||
next_step++;
|
||||
|
||||
if (next_step != state.step) {
|
||||
state.step = next_step;
|
||||
if (next_step >= state.profile_steps) {
|
||||
if (next_step != current_state.step) {
|
||||
current_state.step = next_step;
|
||||
if (next_step >= current_state.profile_steps) {
|
||||
(void)temp_profile_executer_stop();
|
||||
} else {
|
||||
cmd_continue = false;
|
||||
@@ -274,15 +315,15 @@ int temp_profile_executer_handle(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct tpe_current_state *temp_profile_executer_status(void)
|
||||
const struct tpe_exec_state *temp_profile_executer_status(void)
|
||||
{
|
||||
return &state;
|
||||
return ¤t_state;
|
||||
}
|
||||
|
||||
int temp_profile_executer_stop(void)
|
||||
{
|
||||
if (state.status == TPE_RUNNING) {
|
||||
state.status = TPE_OFF;
|
||||
if (current_state.status == TPE_RUNNING) {
|
||||
current_state.status = TPE_OFF;
|
||||
oven_pid_stop();
|
||||
}
|
||||
|
||||
@@ -290,7 +331,9 @@ int temp_profile_executer_stop(void)
|
||||
if (command_list)
|
||||
temp_profile_free_command_list(&command_list);
|
||||
|
||||
/* Reset loudspeaker and reset default state of DIGIO channels */
|
||||
loudspeaker_set(0);
|
||||
digio_set_default_values();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -48,6 +48,9 @@ static const struct pl_command_list_map cmd_list_map[_PL_NUM_CMDS] = {
|
||||
{PL_LOUDSPEAKER_SET, "beep", 1u},
|
||||
{PL_OFF, "temp_off", 0u},
|
||||
{PL_CLEAR_FLAGS, "clear_flags", 0u},
|
||||
{PL_DIGIO_CONF, "digio_conf", 2u},
|
||||
{PL_DIGIO_SET, "digio_set", 2u},
|
||||
{PL_DIGIO_WAIT, "digio_wait", 2u},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -108,6 +111,13 @@ static const struct pl_command_list_map *string_to_command(const char *str)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse a line in the temperature profile to a command.
|
||||
* @param line Line to parse
|
||||
* @param[out] cmd Command parsed
|
||||
* @return negative in case of an error (Invalid command, invalid line);
|
||||
* 1 in case the line is an empty line.
|
||||
*/
|
||||
static int parse_line(char *line, struct pl_command *cmd)
|
||||
{
|
||||
uint8_t token_idx = 0;
|
||||
@@ -123,7 +133,10 @@ static int parse_line(char *line, struct pl_command *cmd)
|
||||
token = strtok(line, delim);
|
||||
|
||||
if (!token) {
|
||||
/* Empty line or command line */
|
||||
/* Empty line.
|
||||
* Note: The comments in the lines are already filteed out before calling this function.
|
||||
* Therefore, the empty line case covers lines containing just a comment
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -131,6 +144,10 @@ static int parse_line(char *line, struct pl_command *cmd)
|
||||
switch (token_idx) {
|
||||
case 0:
|
||||
map = string_to_command(token);
|
||||
if (!map) {
|
||||
/* No valid command found */
|
||||
return -1;
|
||||
}
|
||||
c.cmd = map->command;
|
||||
break;
|
||||
default:
|
||||
@@ -162,12 +179,23 @@ static int parse_line(char *line, struct pl_command *cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append a command to a singly linked list.
|
||||
*
|
||||
* The the list item is newly allocated and the command is copied. Therefore, \p cmd can be overwritten after
|
||||
* a call to this function.
|
||||
*
|
||||
* @param list List to add the command to
|
||||
* @param cmd Command to add to list
|
||||
* @return The new head of the list. If an error occured */
|
||||
static SlList *copy_and_append_command_to_list(SlList *list, const struct pl_command *cmd)
|
||||
{
|
||||
struct pl_command *alloced_cmd;
|
||||
|
||||
alloced_cmd = (struct pl_command *)malloc(sizeof(struct pl_command));
|
||||
memcpy(alloced_cmd, cmd, sizeof(struct pl_command));
|
||||
|
||||
/* This will go catastrophically wrong, if the heap is full... just saying. */
|
||||
list = sl_list_append(list, alloced_cmd);
|
||||
|
||||
return list;
|
||||
@@ -235,6 +263,10 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free an allocated pl_command structure
|
||||
* @param cmd command struct. Tolerates NULL.
|
||||
*/
|
||||
static void delete_pl_command(void *cmd)
|
||||
{
|
||||
if (cmd)
|
||||
|
@@ -414,7 +414,7 @@ static SlList *load_file_list_from_sdcard(int *error, const char *file_pattern)
|
||||
static void gui_menu_temp_profile_execute(struct lcd_menu *menu, enum menu_entry_func_entry entry_type, void* parent)
|
||||
{
|
||||
static void *my_parent;
|
||||
const struct tpe_current_state *state;
|
||||
const struct tpe_exec_state *state;
|
||||
static uint64_t last_tick;
|
||||
float temperature;
|
||||
float resistance;
|
||||
@@ -663,21 +663,26 @@ static void gui_update_firmware(struct lcd_menu *menu, enum menu_entry_func_entr
|
||||
}
|
||||
}
|
||||
|
||||
if (entry_type == MENU_ENTRY_FIRST_ENTER ||
|
||||
previously_selected_file != currently_selected_file) {
|
||||
fname = sl_list_nth(file_list, currently_selected_file)->data;
|
||||
menu_lcd_output(menu, 0, "Select File:");
|
||||
if (fname)
|
||||
menu_lcd_output(menu, 1, fname);
|
||||
if (list_length) {
|
||||
if (entry_type == MENU_ENTRY_FIRST_ENTER ||
|
||||
previously_selected_file != currently_selected_file) {
|
||||
fname = sl_list_nth(file_list, currently_selected_file)->data;
|
||||
menu_lcd_output(menu, 0, "Select File:");
|
||||
if (fname)
|
||||
menu_lcd_output(menu, 1, fname);
|
||||
}
|
||||
if (button == BUTTON_SHORT_RELEASED) {
|
||||
fname = sl_list_nth(file_list, currently_selected_file)->data;
|
||||
menu_display_clear(menu);
|
||||
updater_update_from_file(fname);
|
||||
/* This code is here for completeness. It will never be reached! */
|
||||
sl_list_free_full(file_list, delete_file_list_entry);
|
||||
}
|
||||
} else {
|
||||
menu_lcd_output(menu, 0, "No files!");
|
||||
}
|
||||
if (button == BUTTON_SHORT_RELEASED) {
|
||||
fname = sl_list_nth(file_list, currently_selected_file)->data;
|
||||
menu_display_clear(menu);
|
||||
file_list = NULL;
|
||||
updater_update_from_file(fname);
|
||||
/* This code is here for completeness. It will never be reached! */
|
||||
sl_list_free_full(file_list, delete_file_list_entry);
|
||||
} else if (button == BUTTON_LONG) {
|
||||
|
||||
if (button == BUTTON_LONG) {
|
||||
sl_list_free_full(file_list, delete_file_list_entry);
|
||||
file_list = NULL;
|
||||
menu_entry_dropback(menu, my_parent);
|
||||
@@ -686,6 +691,37 @@ static void gui_update_firmware(struct lcd_menu *menu, enum menu_entry_func_entr
|
||||
}
|
||||
}
|
||||
|
||||
static void gui_connector_info(struct lcd_menu *menu, enum menu_entry_func_entry entry_type, void *parent)
|
||||
{
|
||||
static void *my_parent;
|
||||
enum button_state button;
|
||||
|
||||
if (entry_type == MENU_ENTRY_FIRST_ENTER) {
|
||||
my_parent = parent;
|
||||
menu_display_clear(menu);
|
||||
|
||||
menu_lcd_output(menu, 0, "2,4: DIGIO[0,1]");
|
||||
menu_lcd_output(menu, 1, "6: DIGIO2 (TX)");
|
||||
menu_lcd_output(menu, 2, "8: DIGIO3 (RX)");
|
||||
menu_lcd_output(menu, 3, "10:3V3 Rest:GND");
|
||||
}
|
||||
|
||||
if (menu_get_button_ready_state(menu)) {
|
||||
/* Buttons are ready. Read button */
|
||||
button = menu_get_button_state(menu);
|
||||
/* Throw away any rotation */
|
||||
(void)menu_get_rotary_delta(menu);
|
||||
|
||||
if (button == BUTTON_SHORT_RELEASED || button == BUTTON_LONG ||
|
||||
button == BUTTON_LONG_RELEASED) {
|
||||
/* Exit menu */
|
||||
menu_entry_dropback(menu, my_parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static char *overlay_heading = NULL;
|
||||
static char *overlay_text = NULL;
|
||||
|
||||
@@ -735,6 +771,7 @@ static void gui_menu_root_entry(struct lcd_menu *menu, enum menu_entry_func_entr
|
||||
"Error Flags",
|
||||
"About",
|
||||
"Update",
|
||||
"Connector Info",
|
||||
NULL
|
||||
};
|
||||
static const menu_func_t root_entry_funcs[] = {
|
||||
@@ -744,6 +781,7 @@ static void gui_menu_root_entry(struct lcd_menu *menu, enum menu_entry_func_entr
|
||||
gui_menu_err_flags,
|
||||
gui_menu_about,
|
||||
gui_update_firmware,
|
||||
gui_connector_info,
|
||||
};
|
||||
enum button_state push_button;
|
||||
int16_t rot_delta;
|
||||
@@ -815,10 +853,16 @@ int gui_handle(void)
|
||||
|
||||
void gui_init(void)
|
||||
{
|
||||
/** - Setup the rotary encoder input */
|
||||
rotary_encoder_setup();
|
||||
|
||||
/** - Setup the push button */
|
||||
button_init();
|
||||
|
||||
/** - Setup the LCD */
|
||||
lcd_init();
|
||||
|
||||
/** - If an overlay has been previously set, clear it */
|
||||
if (overlay_heading)
|
||||
free(overlay_heading);
|
||||
if (overlay_text)
|
||||
@@ -827,6 +871,7 @@ void gui_init(void)
|
||||
overlay_heading = NULL;
|
||||
overlay_text = NULL;
|
||||
|
||||
/** - Init the GUI menu */
|
||||
menu_init(reflow_menu_ptr, gui_menu_root_entry, update_display_buffer);
|
||||
}
|
||||
|
||||
@@ -853,3 +898,13 @@ void gui_lcd_write_direct_blocking(uint8_t line, const char *text)
|
||||
lcd_setcursor(0, line);
|
||||
lcd_string(text);
|
||||
}
|
||||
|
||||
size_t gui_get_line_count(void)
|
||||
{
|
||||
return (size_t)LCD_ROW_COUNT;
|
||||
}
|
||||
|
||||
const char (*gui_get_current_display_content(void))[21]
|
||||
{
|
||||
return display_buffer;
|
||||
}
|
||||
|
130
stm-firmware/ui/shell-uart.c
Normal file
130
stm-firmware/ui/shell-uart.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/* Reflow Oven Controller
|
||||
*
|
||||
* Copyright (C) 2021 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/ui/shell-uart.h>
|
||||
#include <reflow-controller/periph-config/shell-uart-config.h>
|
||||
#include <stm-periph/stm32-gpio-macros.h>
|
||||
#include <stm-periph/uart.h>
|
||||
#include <helper-macros/helper-macros.h>
|
||||
|
||||
/**
|
||||
* @brief TX buffer for the shell's uart
|
||||
*/
|
||||
static char shell_uart_tx_buff[4096];
|
||||
|
||||
/**
|
||||
* @brief RX buffer for the shell's uart
|
||||
*/
|
||||
static char shell_uart_rx_buff[128];
|
||||
|
||||
/**
|
||||
* @brief The uart instance handling the shellmatta shell.
|
||||
*/
|
||||
struct stm_uart shell_uart;
|
||||
|
||||
void shell_uart_setup(void)
|
||||
{
|
||||
struct stm_uart *uart = &shell_uart;
|
||||
|
||||
uart->rx = 1;
|
||||
uart->tx = 1;
|
||||
uart->brr_val = SHELL_UART_DEFAULT_BRR_REG_VALUE;
|
||||
uart->rcc_reg = &SHELL_UART_RCC_REG;
|
||||
uart->rcc_bit_no = BITMASK_TO_BITNO(SHELL_UART_RCC_MASK);
|
||||
uart->uart_dev = SHELL_UART_PERIPH;
|
||||
uart->dma_rx_buff = shell_uart_rx_buff;
|
||||
uart->dma_tx_buff = shell_uart_tx_buff;
|
||||
uart->rx_buff_count = sizeof(shell_uart_rx_buff);
|
||||
uart->tx_buff_count = sizeof(shell_uart_tx_buff);
|
||||
uart->base_dma_num = 2;
|
||||
uart->dma_rx_stream = SHELL_UART_RECEIVE_DMA_STREAM;
|
||||
uart->dma_tx_stream = SHELL_UART_SEND_DMA_STREAM;
|
||||
uart->dma_rx_trigger_channel = SHELL_UART_RX_DMA_TRIGGER;
|
||||
uart->dma_tx_trigger_channel = SHELL_UART_TX_DMA_TRIGGER;
|
||||
|
||||
uart_init(uart);
|
||||
NVIC_EnableIRQ(DMA2_Stream7_IRQn);
|
||||
}
|
||||
|
||||
shellmatta_retCode_t shell_uart_write_callback(const char *data, uint32_t len)
|
||||
{
|
||||
uart_send_array_with_dma(&shell_uart, data, len);
|
||||
return SHELLMATTA_OK;
|
||||
}
|
||||
|
||||
int shell_uart_receive_data_with_dma(const char **data, size_t *len)
|
||||
{
|
||||
return uart_receive_data_with_dma(&shell_uart, data, len);
|
||||
}
|
||||
|
||||
int32_t shell_uart_reconfig_baud(uint32_t new_baud)
|
||||
{
|
||||
uint32_t brr_val_floor;
|
||||
uint32_t brr_val_remainder;
|
||||
uint32_t error_permille;
|
||||
int64_t actual_baud;
|
||||
|
||||
/* Calculate the new BRR register value */
|
||||
brr_val_floor = SHELL_UART_PERIPHERAL_CLOCK / new_baud;
|
||||
brr_val_remainder = SHELL_UART_PERIPHERAL_CLOCK % new_baud;
|
||||
|
||||
/* Round to the nearest value */
|
||||
if (brr_val_remainder > (new_baud / 2u)) {
|
||||
brr_val_floor++;
|
||||
brr_val_remainder = new_baud - brr_val_remainder;
|
||||
}
|
||||
|
||||
actual_baud = (1000U *(int64_t)SHELL_UART_PERIPHERAL_CLOCK) / brr_val_floor;
|
||||
error_permille = (ABS(actual_baud - 1000U * (int64_t)new_baud)) / (int64_t)new_baud;
|
||||
|
||||
|
||||
if (error_permille < 20u) {
|
||||
uart_change_brr(&shell_uart, brr_val_floor);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int32_t)error_permille;
|
||||
}
|
||||
|
||||
uint32_t shell_uart_get_current_baudrate(void)
|
||||
{
|
||||
uint32_t brr;
|
||||
|
||||
brr = uart_get_brr(&shell_uart);
|
||||
if (brr == 0)
|
||||
return 0;
|
||||
|
||||
return (SHELL_UART_PERIPHERAL_CLOCK) / brr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handles the TX of UART1 (Shellmatta)
|
||||
*/
|
||||
void DMA2_Stream7_IRQHandler(void)
|
||||
{
|
||||
uint32_t hisr = DMA2->HISR & (0x3F << 22);
|
||||
|
||||
DMA2->HIFCR = hisr;
|
||||
|
||||
if (hisr & DMA_HISR_TCIF7)
|
||||
uart_tx_dma_complete_int_callback(&shell_uart);
|
||||
}
|
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <stm32/stm32f4xx.h>
|
||||
#include <cmsis/core_cm4.h>
|
||||
#include <reflow-controller/shell.h>
|
||||
#include <reflow-controller/ui/shell.h>
|
||||
#include <stm-periph/uart.h>
|
||||
#include <string.h>
|
||||
#include <reflow-controller/adc-meas.h>
|
||||
@@ -46,6 +46,8 @@
|
||||
#include <reflow-controller/updater/updater.h>
|
||||
#include <reflow-controller/main-cycle-counter.h>
|
||||
#include <stm-periph/option-bytes.h>
|
||||
#include <reflow-controller/ui/gui.h>
|
||||
#include <reflow-controller/ui/shell-uart.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -68,6 +70,10 @@ static shellmatta_retCode_t shell_cmd_ver(const shellmatta_handle_t handle,
|
||||
uint32_t high_id;
|
||||
uint32_t stm_rev_id;
|
||||
uint32_t stm_dev_id;
|
||||
uint8_t core_rev;
|
||||
uint8_t core_implementer;
|
||||
uint8_t core_variant;
|
||||
uint16_t core_part_no;
|
||||
const char *hw_rev_str;
|
||||
enum hw_revision pcb_rev;
|
||||
|
||||
@@ -75,7 +81,7 @@ static shellmatta_retCode_t shell_cmd_ver(const shellmatta_handle_t handle,
|
||||
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");
|
||||
"Compiled: " __DATE__ " at " __TIME__ "\r\n");
|
||||
shellmatta_printf(handle, "Serial: %08X-%08X-%08X\r\n", high_id, mid_id, low_id);
|
||||
|
||||
pcb_rev = get_pcb_hardware_version();
|
||||
@@ -86,6 +92,9 @@ static shellmatta_retCode_t shell_cmd_ver(const shellmatta_handle_t handle,
|
||||
case HW_REV_V1_3:
|
||||
hw_rev_str = "Hardware: v1.3";
|
||||
break;
|
||||
case HW_REV_V1_3_1:
|
||||
hw_rev_str = "Hardware: v1.3.1";
|
||||
break;
|
||||
default:
|
||||
hw_rev_str = "Hardware: Unknown Revision. You might have to update the firmware!";
|
||||
break;
|
||||
@@ -95,6 +104,12 @@ static shellmatta_retCode_t shell_cmd_ver(const shellmatta_handle_t handle,
|
||||
shellmatta_printf(handle, "STM Device ID: 0x%04X\r\n", stm_dev_id);
|
||||
shellmatta_printf(handle, "STM Revision ID: 0x%04X\r\n", stm_rev_id);
|
||||
|
||||
stm_cpuid_get(&core_implementer, &core_variant, &core_part_no, &core_rev);
|
||||
shellmatta_printf(handle, "CPU Implementer: 0x%02X\r\n", (unsigned int)core_implementer);
|
||||
shellmatta_printf(handle, "CPU Variant: 0x%02X\r\n", (unsigned int)core_variant);
|
||||
shellmatta_printf(handle, "CPU Part No.: 0x%04X\r\n", (unsigned int)core_part_no);
|
||||
shellmatta_printf(handle, "CPU Revision: 0x%02X\r\n", (unsigned int)core_rev);
|
||||
|
||||
return SHELLMATTA_OK;
|
||||
}
|
||||
|
||||
@@ -481,6 +496,11 @@ static shellmatta_retCode_t shell_cmd_ui_emulation(const shellmatta_handle_t han
|
||||
uint32_t i;
|
||||
uint32_t len;
|
||||
char *buff;
|
||||
uint8_t row;
|
||||
uint8_t col;
|
||||
bool disp_content_differs = false;
|
||||
static char IN_SECTION(.ccm.bss) display_buffer[4][21] = {0};
|
||||
const char (*current_display)[21];
|
||||
|
||||
shellmatta_read(handle, &buff, &len);
|
||||
|
||||
@@ -509,6 +529,39 @@ static shellmatta_retCode_t shell_cmd_ui_emulation(const shellmatta_handle_t han
|
||||
case 'R':
|
||||
button_override_event(BUTTON_LONG_RELEASED);
|
||||
break;
|
||||
case '\x03':
|
||||
/* CTRL-C received. Delete the display buffer so it will be updated the next time
|
||||
* This function is called.
|
||||
* Otherwise the diplay might not be printed to the console if nothing has changed
|
||||
*/
|
||||
display_buffer[0][0] = 0;
|
||||
display_buffer[1][0] = 0;
|
||||
display_buffer[2][0] = 0;
|
||||
display_buffer[3][0] = 0;
|
||||
return SHELLMATTA_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
current_display = gui_get_current_display_content();
|
||||
|
||||
for (row = 0; row < 4; row++) {
|
||||
for (col = 0; col < 21; col++) {
|
||||
if (current_display[row][col] != display_buffer[row][col]) {
|
||||
display_buffer[row][col] = current_display[row][col];
|
||||
disp_content_differs = true;
|
||||
}
|
||||
}
|
||||
display_buffer[row][20] = 0;
|
||||
}
|
||||
|
||||
if (disp_content_differs) {
|
||||
/* Clear the display */
|
||||
shellmatta_printf(handle, "\e[2J\e[H");
|
||||
|
||||
/* Print out the rows of the LCD to console */
|
||||
for (row = 0; row < 4; row++) {
|
||||
shellmatta_printf(handle, "%s\r\n", &display_buffer[row][0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -725,7 +778,7 @@ shellmatta_retCode_t shell_cmd_overtemp_cfg(const shellmatta_handle_t handle, co
|
||||
shellmatta_retCode_t shell_cmd_execute(const shellmatta_handle_t handle, const char *args, uint32_t len)
|
||||
{
|
||||
enum pl_ret_val res;
|
||||
const struct tpe_current_state *state;
|
||||
const struct tpe_exec_state *state;
|
||||
static bool running = false;
|
||||
char *data;
|
||||
uint32_t dlen;
|
||||
@@ -806,6 +859,7 @@ shellmatta_retCode_t shell_cmd_execute(const shellmatta_handle_t handle, const c
|
||||
shellmatta_retCode_t shell_cmd_cycle_count(const shellmatta_handle_t handle, const char *args, uint32_t len)
|
||||
{
|
||||
uint64_t counter;
|
||||
uint32_t core_cycle_count;
|
||||
(void)args;
|
||||
(void)len;
|
||||
char option;
|
||||
@@ -813,8 +867,10 @@ shellmatta_retCode_t shell_cmd_cycle_count(const shellmatta_handle_t handle, con
|
||||
uint32_t arg_len;
|
||||
int opt_stat;
|
||||
bool clear = false;
|
||||
bool hex = false;
|
||||
const shellmatta_opt_long_t options[] = {
|
||||
{"clear", 'c', SHELLMATTA_OPT_ARG_NONE},
|
||||
{"hex", 'h', SHELLMATTA_OPT_ARG_NONE},
|
||||
{NULL, '\0', SHELLMATTA_OPT_ARG_NONE},
|
||||
};
|
||||
|
||||
@@ -826,6 +882,8 @@ shellmatta_retCode_t shell_cmd_cycle_count(const shellmatta_handle_t handle, con
|
||||
case 'c':
|
||||
clear = true;
|
||||
break;
|
||||
case 'h':
|
||||
hex = true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -833,10 +891,18 @@ shellmatta_retCode_t shell_cmd_cycle_count(const shellmatta_handle_t handle, con
|
||||
|
||||
|
||||
counter = main_cycle_counter_get();
|
||||
shellmatta_printf(handle, "%"PRIu64"\r\n", counter);
|
||||
if (clear)
|
||||
core_cycle_count = DWT->CYCCNT;
|
||||
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);
|
||||
} else {
|
||||
shellmatta_printf(handle, "Main loop: %"PRIu64"\r\n", counter);
|
||||
shellmatta_printf(handle, "CPU cycles: %"PRIu32"\r\n", core_cycle_count);
|
||||
}
|
||||
if (clear) {
|
||||
main_cycle_counter_init();
|
||||
|
||||
DWT->CYCCNT = 0UL;
|
||||
}
|
||||
return SHELLMATTA_OK;
|
||||
}
|
||||
|
||||
@@ -904,6 +970,56 @@ shellmatta_retCode_t shell_cmd_print_opt_bytes(const shellmatta_handle_t handle,
|
||||
return SHELLMATTA_OK;
|
||||
}
|
||||
|
||||
shellmatta_retCode_t shell_cmd_set_baud(const shellmatta_handle_t handle, const char *args, uint32_t len)
|
||||
{
|
||||
|
||||
shellmatta_retCode_t opt_stat;
|
||||
char option;
|
||||
char *argument;
|
||||
uint32_t arg_len;
|
||||
char *baud_string = NULL;
|
||||
uint32_t baud;
|
||||
(void)len;
|
||||
(void)args;
|
||||
|
||||
const shellmatta_opt_long_t options[] = {
|
||||
{NULL, '\0', SHELLMATTA_OPT_ARG_NONE},
|
||||
};
|
||||
|
||||
while (1) {
|
||||
opt_stat = shellmatta_opt_long(handle, options, &option, &argument, &arg_len);
|
||||
if (opt_stat != SHELLMATTA_OK)
|
||||
break;
|
||||
switch (option) {
|
||||
case '\0':
|
||||
baud_string = argument;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
shellmatta_printf(handle, "Current baudrate: %u\r\n", (unsigned int)shell_uart_get_current_baudrate());
|
||||
|
||||
if (!baud_string) {
|
||||
shellmatta_printf(handle, "Please specify a baudrate\r\n");
|
||||
return SHELLMATTA_OK;
|
||||
}
|
||||
|
||||
baud = strtoul(baud_string, NULL, 0);
|
||||
if (baud < 38400) {
|
||||
shellmatta_printf(handle, "38400 is the minimum recommended baudrate!\r\n");
|
||||
}
|
||||
|
||||
shellmatta_printf(handle, "Setting baud to: %u\r\n", (unsigned int)baud);
|
||||
|
||||
if (shell_uart_reconfig_baud(baud) < 0) {
|
||||
shellmatta_printf(handle,"Setting baudrate not possible. Error greater than 2%%\r\n");
|
||||
}
|
||||
|
||||
return SHELLMATTA_OK;
|
||||
}
|
||||
|
||||
//typedef struct shellmatta_cmd
|
||||
//{
|
||||
// char *cmd; /**< command name */
|
||||
@@ -913,7 +1029,7 @@ shellmatta_retCode_t shell_cmd_print_opt_bytes(const shellmatta_handle_t handle,
|
||||
// shellmatta_cmdFct_t cmdFct; /**< pointer to the cmd callack function */
|
||||
// struct shellmatta_cmd *next; /**< pointer to next command or NULL */
|
||||
//} shellmatta_cmd_t;
|
||||
static shellmatta_cmd_t cmd[24] = {
|
||||
static shellmatta_cmd_t cmd[25] = {
|
||||
{
|
||||
.cmd = "version",
|
||||
.cmdAlias = "ver",
|
||||
@@ -1105,8 +1221,17 @@ static shellmatta_cmd_t cmd[24] = {
|
||||
.helpText = "Print the currently set option bytes of the STM32",
|
||||
.usageText = "",
|
||||
.cmdFct = shell_cmd_print_opt_bytes,
|
||||
.next = &cmd[24],
|
||||
},
|
||||
{
|
||||
.cmd = "baudrate",
|
||||
.cmdAlias = "baud",
|
||||
.helpText = "Set a new temporary baudrate for the UART",
|
||||
.usageText = "baudrate <new baud>",
|
||||
.cmdFct = shell_cmd_set_baud,
|
||||
.next = NULL,
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
shellmatta_handle_t shell_init(shellmatta_write_t write_func)
|
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,7 @@ void flash_writer_perform_mass_erase(void)
|
||||
flash_writer_enable_access();
|
||||
while (flash_op_busy());
|
||||
|
||||
FLASH->CR = DMA_SxCR_PSIZE_1;
|
||||
FLASH->CR = FLASH_CR_PSIZE_1;
|
||||
FLASH->CR |= FLASH_CR_MER;
|
||||
FLASH->CR |= FLASH_CR_STRT;
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.14 /
|
||||
/ FatFs - Generic FAT Filesystem module R0.14b /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2019, ChaN, all right reserved.
|
||||
/ Copyright (C) 2021, 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 86606 /* Revision ID */
|
||||
#define FF_DEFINED 86631 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -35,10 +35,14 @@ extern "C" {
|
||||
|
||||
/* Integer types used for FatFs API */
|
||||
|
||||
#if defined(_WIN32) /* Main development platform */
|
||||
#if defined(_WIN32) /* Windows VC++ (for development only) */
|
||||
#define FF_INTDEF 2
|
||||
#include <windows.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
#include <float.h>
|
||||
#define isnan(v) _isnan(v)
|
||||
#define isinf(v) (!_finite(v))
|
||||
|
||||
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
|
||||
#define FF_INTDEF 2
|
||||
#include <stdint.h>
|
||||
@@ -48,6 +52,7 @@ typedef uint16_t WORD; /* 16-bit unsigned integer */
|
||||
typedef uint32_t DWORD; /* 32-bit unsigned integer */
|
||||
typedef uint64_t QWORD; /* 64-bit unsigned integer */
|
||||
typedef WORD WCHAR; /* UTF-16 character type */
|
||||
|
||||
#else /* Earlier than C99 */
|
||||
#define FF_INTDEF 1
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
@@ -58,28 +63,29 @@ typedef WORD WCHAR; /* UTF-16 character type */
|
||||
#endif
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
/* Type of file size and LBA variables */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition mapping table */
|
||||
#if FF_FS_EXFAT
|
||||
#if FF_INTDEF != 2
|
||||
#error exFAT feature wants C99 or later
|
||||
#endif
|
||||
|
||||
#if FF_STR_VOLUME_ID
|
||||
#ifndef FF_VOLUME_STRS
|
||||
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||
typedef QWORD FSIZE_t;
|
||||
#if FF_LBA64
|
||||
typedef QWORD LBA_t;
|
||||
#else
|
||||
typedef DWORD LBA_t;
|
||||
#endif
|
||||
#else
|
||||
#if FF_LBA64
|
||||
#error exFAT needs to be enabled when enable 64-bit LBA
|
||||
#endif
|
||||
typedef DWORD FSIZE_t;
|
||||
typedef DWORD LBA_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#ifndef _INC_TCHAR
|
||||
#define _INC_TCHAR
|
||||
/* Type of path name strings on FatFs API (TCHAR) */
|
||||
|
||||
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||
typedef WCHAR TCHAR;
|
||||
@@ -101,28 +107,22 @@ typedef char TCHAR;
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
/* Type of file size and LBA variables */
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition mapping table */
|
||||
#endif
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
#if FF_INTDEF != 2
|
||||
#error exFAT feature wants C99 or later
|
||||
#if FF_STR_VOLUME_ID
|
||||
#ifndef FF_VOLUME_STRS
|
||||
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||
#endif
|
||||
typedef QWORD FSIZE_t;
|
||||
#if FF_LBA64
|
||||
typedef QWORD LBA_t;
|
||||
#else
|
||||
typedef DWORD LBA_t;
|
||||
#endif
|
||||
#else
|
||||
#if FF_LBA64
|
||||
#error exFAT needs to be enabled when enable 64-bit LBA
|
||||
#endif
|
||||
typedef DWORD FSIZE_t;
|
||||
typedef DWORD LBA_t;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -345,10 +345,6 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the fil
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
/ FatFs Functional Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 86606 /* Revision ID */
|
||||
#define FFCONF_DEF 86631 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
@@ -25,15 +25,7 @@
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 1
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 0
|
||||
#define FF_USE_FIND 1
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
@@ -64,6 +56,30 @@
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 1
|
||||
#define FF_PRINT_LLI 0
|
||||
#define FF_PRINT_FLOAT 0
|
||||
#define FF_STRF_ENCODE 0
|
||||
/* FF_USE_STRFUNC switches string functions, f_gets(), f_putc(), f_puts() and
|
||||
/ f_printf().
|
||||
/
|
||||
/ 0: Disable. FF_PRINT_LLI, FF_PRINT_FLOAT and FF_STRF_ENCODE have no effect.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 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.
|
||||
/ 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.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
@@ -137,19 +153,6 @@
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#define FF_STRF_ENCODE 3
|
||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
||||
/ This option selects assumption of character encoding ON THE FILE to be
|
||||
/ read/written via those functions.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 0
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
@@ -194,7 +197,7 @@
|
||||
#define FF_MAX_SS 512
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ harddisk, but a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
@@ -205,8 +208,8 @@
|
||||
/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */
|
||||
|
||||
|
||||
#define FF_MIN_GPT 0x100000000
|
||||
/* Minimum number of sectors to switch GPT format to create partition in f_mkfs and
|
||||
#define FF_MIN_GPT 0x10000000
|
||||
/* Minimum number of sectors to switch GPT as partitioning format in f_mkfs and
|
||||
/ f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */
|
||||
|
||||
|
||||
@@ -228,7 +231,7 @@
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 0
|
||||
#define FF_FS_EXFAT 1
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
@@ -237,7 +240,7 @@
|
||||
#define FF_FS_NORTC 0
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2019
|
||||
#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
|
||||
|
@@ -6,7 +6,7 @@
|
||||
void uart_init(void)
|
||||
{
|
||||
SHELL_UART_RCC_REG |= SHELL_UART_RCC_MASK;
|
||||
SHELL_UART_PERIPH->BRR = SHELL_UART_BRR_REG_VALUE;
|
||||
SHELL_UART_PERIPH->BRR = SHELL_UART_DEFAULT_BRR_REG_VALUE;
|
||||
SHELL_UART_PERIPH->CR2 = 0;
|
||||
SHELL_UART_PERIPH->CR3 = 0;
|
||||
SHELL_UART_PERIPH->CR1 = USART_CR1_TE | USART_CR1_UE;
|
||||
|
Reference in New Issue
Block a user