Compare commits
8 Commits
new_UI
...
10e1609c23
| Author | SHA1 | Date | |
|---|---|---|---|
| 10e1609c23 | |||
| 20cb59ee6d | |||
| 859b196d9e | |||
| e0c7f20970 | |||
| f92f6de5bf | |||
| a3c38516d3 | |||
| f2004bdc35 | |||
| 03bb95db58 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1 @@
|
||||
|
||||
build*
|
||||
|
||||
27
.mxproject
Normal file
27
.mxproject
Normal file
File diff suppressed because one or more lines are too long
11
.project
Normal file
11
.project
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>RadioPhotonic_PCB_software</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
11
.project.bak
Normal file
11
.project.bak
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>For_stm32_2023_12_08</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
1772
App/Core/app_core.c
1772
App/Core/app_core.c
File diff suppressed because it is too large
Load Diff
@ -1,66 +0,0 @@
|
||||
/**
|
||||
* @file app_core.h
|
||||
* @brief Top-level application runtime and IRQ entry points.
|
||||
*/
|
||||
|
||||
#ifndef APP_CORE_H
|
||||
#define APP_CORE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "app_types.h"
|
||||
|
||||
/**
|
||||
* @brief Initialise the modular application layer after CubeMX peripherals are ready.
|
||||
*/
|
||||
void app_init(void);
|
||||
|
||||
/**
|
||||
* @brief Execute one non-blocking iteration of the top-level application state machine.
|
||||
*/
|
||||
void app_run_once(void);
|
||||
|
||||
/**
|
||||
* @brief Post a deferred application event from an ISR, button handler, or future UI backend.
|
||||
*
|
||||
* The event is latched and consumed inside `app_run_once()` so hardware-facing
|
||||
* interrupt adapters stay thin and the main runtime keeps ownership of mode
|
||||
* transitions and safe-stop sequencing.
|
||||
*
|
||||
* @param event Event to enqueue for the application core.
|
||||
*/
|
||||
void app_post_event(app_event_t event);
|
||||
|
||||
/**
|
||||
* @brief Forward one raw UART byte into the transport-agnostic protocol parser.
|
||||
*
|
||||
* @param byte Newly received UART byte.
|
||||
*/
|
||||
void app_on_uart_byte(uint8_t byte);
|
||||
|
||||
/**
|
||||
* @brief Notify the application core about a UART framing/parity/overrun error.
|
||||
*/
|
||||
void app_on_uart_error(void);
|
||||
|
||||
/**
|
||||
* @brief Notify the application core about the 10 ms housekeeping tick.
|
||||
*/
|
||||
void app_on_tim6_tick(void);
|
||||
|
||||
/**
|
||||
* @brief Notify the application core about the 1 ms timebase tick.
|
||||
*/
|
||||
void app_on_tim7_tick(void);
|
||||
|
||||
/**
|
||||
* @brief Notify the application core about the fast TEC modulation tick.
|
||||
*/
|
||||
void app_on_tim5_tick(void);
|
||||
|
||||
/**
|
||||
* @brief Notify the application core that the USART DMA transmit finished.
|
||||
*/
|
||||
void app_on_dma_tx_complete(void);
|
||||
|
||||
#endif /* APP_CORE_H */
|
||||
@ -1,716 +0,0 @@
|
||||
/**
|
||||
* @file ad9102_device.c
|
||||
* @brief AD9102 waveform-generation device driver.
|
||||
*/
|
||||
|
||||
#include "ad9102_device.h"
|
||||
|
||||
#include "board_io.h"
|
||||
#include "main.h"
|
||||
|
||||
/* AD9102 register map used by the existing firmware. See ad9102.pdf. */
|
||||
#define AD9102_REG_SPICONFIG 0x0000u
|
||||
#define AD9102_REG_POWERCONFIG 0x0001u
|
||||
#define AD9102_REG_CLOCKCONFIG 0x0002u
|
||||
#define AD9102_REG_RAMUPDATE 0x001Du
|
||||
#define AD9102_REG_PAT_STATUS 0x001Eu
|
||||
#define AD9102_REG_PAT_TYPE 0x001Fu
|
||||
#define AD9102_REG_WAV_CONFIG 0x0027u
|
||||
#define AD9102_REG_PAT_TIMEBASE 0x0028u
|
||||
#define AD9102_REG_PAT_PERIOD 0x0029u
|
||||
#define AD9102_REG_DAC_PAT 0x002Bu
|
||||
#define AD9102_REG_SAW_CONFIG 0x0037u
|
||||
#define AD9102_REG_START_DLY 0x005Cu
|
||||
#define AD9102_REG_START_ADDR 0x005Du
|
||||
#define AD9102_REG_STOP_ADDR 0x005Eu
|
||||
#define AD9102_REG_CFG_ERROR 0x0060u
|
||||
#define AD9102_REG_SRAM_DATA_BASE 0x6000u
|
||||
|
||||
#define AD9102_PAT_STATUS_RUN (1u << 0)
|
||||
|
||||
#define AD9102_SAW_TYPE_UP 0u
|
||||
#define AD9102_SAW_TYPE_TRIANGLE 2u
|
||||
|
||||
#define AD9102_SAW_STEP_DEFAULT 1u
|
||||
#define AD9102_PAT_PERIOD_BASE_DEFAULT 0x2u
|
||||
#define AD9102_START_DELAY_BASE_DEFAULT 0x1u
|
||||
#define AD9102_PAT_TIMEBASE_HOLD_DEFAULT 0x1u
|
||||
#define AD9102_PAT_PERIOD_DEFAULT 0xFFFFu
|
||||
|
||||
#define AD9102_EX4_WAV_CONFIG 0x3212u
|
||||
#define AD9102_EX4_SAW_CONFIG 0x0606u
|
||||
#define AD9102_EX2_WAV_CONFIG 0x3030u
|
||||
#define AD9102_EX2_DAC_PAT 0x0101u
|
||||
#define AD9102_EX2_SAW_CONFIG 0x0200u
|
||||
#define AD9102_SRAM_PAT_PERIOD_BASE_DEFAULT 0x1u
|
||||
#define AD9102_SRAM_START_DELAY_BASE_DEFAULT 0x1u
|
||||
#define AD9102_SRAM_START_DLY_DEFAULT 0x0000u
|
||||
#define AD9102_SRAM_RAMP_MIN (-8192)
|
||||
#define AD9102_SRAM_RAMP_MAX (8191)
|
||||
|
||||
#define AD9102_REG_COUNT 66u
|
||||
#define AD9102_WAVE_MAX_CHUNK_SAMPLES 12u
|
||||
|
||||
static const uint16_t g_ad9102_reg_addr[AD9102_REG_COUNT] = {
|
||||
0x0000u, 0x0001u, 0x0002u, 0x0003u, 0x0004u, 0x0005u, 0x0006u, 0x0007u,
|
||||
0x0008u, 0x0009u, 0x000Au, 0x000Bu, 0x000Cu, 0x000Du, 0x000Eu, 0x001Fu,
|
||||
0x0020u, 0x0022u, 0x0023u, 0x0024u, 0x0025u, 0x0026u, 0x0027u, 0x0028u,
|
||||
0x0029u, 0x002Au, 0x002Bu, 0x002Cu, 0x002Du, 0x002Eu, 0x002Fu, 0x0030u,
|
||||
0x0031u, 0x0032u, 0x0033u, 0x0034u, 0x0035u, 0x0036u, 0x0037u, 0x003Eu,
|
||||
0x003Fu, 0x0040u, 0x0041u, 0x0042u, 0x0043u, 0x0044u, 0x0045u, 0x0047u,
|
||||
0x0050u, 0x0051u, 0x0052u, 0x0053u, 0x0054u, 0x0055u, 0x0056u, 0x0057u,
|
||||
0x0058u, 0x0059u, 0x005Au, 0x005Bu, 0x005Cu, 0x005Du, 0x005Eu, 0x005Fu,
|
||||
0x001Eu, 0x001Du
|
||||
};
|
||||
|
||||
static const uint16_t g_ad9102_example4_regval[AD9102_REG_COUNT] = {
|
||||
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x4000u,
|
||||
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x1F00u, 0x0000u, 0x0000u, 0x0000u,
|
||||
0x000Eu, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x3212u, 0x0121u,
|
||||
0xFFFFu, 0x0000u, 0x0101u, 0x0003u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x4000u, 0x0000u, 0x0606u, 0x1999u,
|
||||
0x9A00u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||
0x0FA0u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x16FFu,
|
||||
0x0001u, 0x0001u
|
||||
};
|
||||
|
||||
static const uint16_t g_ad9102_example2_regval[AD9102_REG_COUNT] = {
|
||||
0x0000u, 0x0E00u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x4000u,
|
||||
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x1F00u, 0x0000u, 0x0000u, 0x0000u,
|
||||
0x000Eu, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x3030u, 0x0111u,
|
||||
0xFFFFu, 0x0000u, 0x0101u, 0x0003u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x4000u, 0x0000u, 0x0200u, 0x0000u,
|
||||
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0FA0u, 0x0000u, 0x3FF0u, 0x0100u,
|
||||
0x0001u, 0x0001u
|
||||
};
|
||||
|
||||
typedef struct ad9102_upload_state_t {
|
||||
uint8_t active;
|
||||
uint16_t expected_samples;
|
||||
uint16_t written_samples;
|
||||
} ad9102_upload_state_t;
|
||||
|
||||
static ad9102_upload_state_t g_upload_state;
|
||||
|
||||
static void ad9102_write_reg(uint16_t address, uint16_t value)
|
||||
{
|
||||
uint16_t command = (uint16_t)(address & 0x7FFFu);
|
||||
uint32_t timeout = 0u;
|
||||
|
||||
board_io_configure_spi2_mode(LL_SPI_POLARITY_LOW, LL_SPI_PHASE_1EDGE);
|
||||
HAL_GPIO_WritePin(DAC_LD1_CS_GPIO_Port, DAC_LD1_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(DAC_TEC1_CS_GPIO_Port, DAC_TEC1_CS_Pin, GPIO_PIN_SET);
|
||||
|
||||
if (!LL_SPI_IsEnabled(SPI2))
|
||||
{
|
||||
LL_SPI_Enable(SPI2);
|
||||
}
|
||||
|
||||
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_RESET);
|
||||
|
||||
while ((!LL_SPI_IsActiveFlag_TXE(SPI2)) && (timeout++ < 1000u))
|
||||
{
|
||||
}
|
||||
LL_SPI_TransmitData16(SPI2, command);
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI2)) && (timeout++ < 1000u))
|
||||
{
|
||||
}
|
||||
(void)SPI2->DR;
|
||||
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_TXE(SPI2)) && (timeout++ < 1000u))
|
||||
{
|
||||
}
|
||||
LL_SPI_TransmitData16(SPI2, value);
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI2)) && (timeout++ < 1000u))
|
||||
{
|
||||
}
|
||||
(void)SPI2->DR;
|
||||
|
||||
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
static uint16_t ad9102_read_reg(uint16_t address)
|
||||
{
|
||||
uint16_t command = (uint16_t)(0x8000u | (address & 0x7FFFu));
|
||||
uint16_t value;
|
||||
uint32_t timeout = 0u;
|
||||
|
||||
board_io_configure_spi2_mode(LL_SPI_POLARITY_LOW, LL_SPI_PHASE_1EDGE);
|
||||
HAL_GPIO_WritePin(DAC_LD1_CS_GPIO_Port, DAC_LD1_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(DAC_TEC1_CS_GPIO_Port, DAC_TEC1_CS_Pin, GPIO_PIN_SET);
|
||||
|
||||
if (!LL_SPI_IsEnabled(SPI2))
|
||||
{
|
||||
LL_SPI_Enable(SPI2);
|
||||
}
|
||||
|
||||
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_RESET);
|
||||
|
||||
while ((!LL_SPI_IsActiveFlag_TXE(SPI2)) && (timeout++ < 1000u))
|
||||
{
|
||||
}
|
||||
LL_SPI_TransmitData16(SPI2, command);
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI2)) && (timeout++ < 1000u))
|
||||
{
|
||||
}
|
||||
(void)SPI2->DR;
|
||||
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_TXE(SPI2)) && (timeout++ < 1000u))
|
||||
{
|
||||
}
|
||||
LL_SPI_TransmitData16(SPI2, 0x0000u);
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI2)) && (timeout++ < 1000u))
|
||||
{
|
||||
}
|
||||
value = LL_SPI_ReceiveData16(SPI2);
|
||||
|
||||
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_SET);
|
||||
return value;
|
||||
}
|
||||
|
||||
static void ad9102_write_reg_table(const uint16_t *values, uint16_t count)
|
||||
{
|
||||
uint16_t index;
|
||||
|
||||
for (index = 0u; index < count; ++index)
|
||||
{
|
||||
ad9102_write_reg(g_ad9102_reg_addr[index], values[index]);
|
||||
}
|
||||
}
|
||||
|
||||
static void ad9102_reset_upload_state(void)
|
||||
{
|
||||
g_upload_state.active = 0u;
|
||||
g_upload_state.expected_samples = 0u;
|
||||
g_upload_state.written_samples = 0u;
|
||||
}
|
||||
|
||||
static void ad9102_start_output(void)
|
||||
{
|
||||
HAL_GPIO_WritePin(AD9102_TRIG_GPIO_Port, AD9102_TRIG_Pin, GPIO_PIN_SET);
|
||||
ad9102_write_reg(AD9102_REG_PAT_STATUS, AD9102_PAT_STATUS_RUN);
|
||||
ad9102_write_reg(AD9102_REG_RAMUPDATE, 0x0001u);
|
||||
|
||||
for (volatile uint32_t delay_counter = 0u; delay_counter < 1000u; ++delay_counter)
|
||||
{
|
||||
}
|
||||
|
||||
HAL_GPIO_WritePin(AD9102_TRIG_GPIO_Port, AD9102_TRIG_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
static void ad9102_configure_sram_playback(uint16_t sample_count, uint8_t hold_cycles)
|
||||
{
|
||||
uint16_t pat_timebase;
|
||||
uint32_t pat_period;
|
||||
|
||||
if (sample_count < 2u)
|
||||
{
|
||||
sample_count = 2u;
|
||||
}
|
||||
if (sample_count > AD9102_SRAM_MAX_SAMPLE_COUNT)
|
||||
{
|
||||
sample_count = AD9102_SRAM_MAX_SAMPLE_COUNT;
|
||||
}
|
||||
if (hold_cycles == 0u)
|
||||
{
|
||||
hold_cycles = AD9102_SRAM_DEFAULT_HOLD;
|
||||
}
|
||||
if (hold_cycles > 0x0Fu)
|
||||
{
|
||||
hold_cycles = 0x0Fu;
|
||||
}
|
||||
|
||||
pat_timebase = (uint16_t)(((uint16_t)(hold_cycles & 0x0Fu) << 8) |
|
||||
((AD9102_SRAM_PAT_PERIOD_BASE_DEFAULT & 0x0Fu) << 4) |
|
||||
(AD9102_SRAM_START_DELAY_BASE_DEFAULT & 0x0Fu));
|
||||
pat_period = (uint32_t)sample_count * (uint32_t)(hold_cycles & 0x0Fu);
|
||||
if (pat_period == 0u)
|
||||
{
|
||||
pat_period = sample_count;
|
||||
}
|
||||
if (pat_period > 0xFFFFu)
|
||||
{
|
||||
pat_period = 0xFFFFu;
|
||||
}
|
||||
|
||||
ad9102_write_reg_table(g_ad9102_example2_regval, AD9102_REG_COUNT);
|
||||
ad9102_stop_output();
|
||||
ad9102_write_reg(AD9102_REG_WAV_CONFIG, AD9102_EX2_WAV_CONFIG);
|
||||
ad9102_write_reg(AD9102_REG_SAW_CONFIG, AD9102_EX2_SAW_CONFIG);
|
||||
ad9102_write_reg(AD9102_REG_DAC_PAT, AD9102_EX2_DAC_PAT);
|
||||
ad9102_write_reg(AD9102_REG_PAT_TIMEBASE, pat_timebase);
|
||||
ad9102_write_reg(AD9102_REG_PAT_PERIOD, (uint16_t)pat_period);
|
||||
ad9102_write_reg(AD9102_REG_PAT_TYPE, 0x0000u);
|
||||
ad9102_write_reg(AD9102_REG_START_DLY, AD9102_SRAM_START_DLY_DEFAULT);
|
||||
ad9102_write_reg(AD9102_REG_START_ADDR, 0x0000u);
|
||||
ad9102_write_reg(AD9102_REG_STOP_ADDR, (uint16_t)((sample_count - 1u) << 4));
|
||||
ad9102_write_reg(AD9102_REG_RAMUPDATE, 0x0001u);
|
||||
}
|
||||
|
||||
static void ad9102_load_sram_ramp(uint16_t sample_count, uint8_t triangle_mode, uint16_t amplitude)
|
||||
{
|
||||
uint16_t sample_index;
|
||||
|
||||
if (sample_count < 2u)
|
||||
{
|
||||
sample_count = 2u;
|
||||
}
|
||||
if (sample_count > AD9102_SRAM_MAX_SAMPLE_COUNT)
|
||||
{
|
||||
sample_count = AD9102_SRAM_MAX_SAMPLE_COUNT;
|
||||
}
|
||||
if (amplitude > AD9102_SRAM_DEFAULT_AMPLITUDE)
|
||||
{
|
||||
amplitude = AD9102_SRAM_DEFAULT_AMPLITUDE;
|
||||
}
|
||||
|
||||
ad9102_write_reg(AD9102_REG_PAT_STATUS, 0x0004u);
|
||||
|
||||
for (sample_index = 0u; sample_index < sample_count; ++sample_index)
|
||||
{
|
||||
int32_t value;
|
||||
int32_t min_value = -(int32_t)amplitude;
|
||||
int32_t max_value = (int32_t)amplitude;
|
||||
int32_t span = max_value - min_value;
|
||||
|
||||
if (triangle_mode != 0u)
|
||||
{
|
||||
uint16_t half = sample_count / 2u;
|
||||
if (half == 0u)
|
||||
{
|
||||
half = 1u;
|
||||
}
|
||||
|
||||
if (sample_index < half)
|
||||
{
|
||||
uint16_t denominator = (half > 1u) ? (uint16_t)(half - 1u) : 1u;
|
||||
value = min_value + (span * (int32_t)sample_index) / (int32_t)denominator;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t tail = (uint16_t)(sample_count - half);
|
||||
uint16_t denominator = (tail > 1u) ? (uint16_t)(tail - 1u) : 1u;
|
||||
value = max_value - (span * (int32_t)(sample_index - half)) / (int32_t)denominator;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t denominator = (sample_count > 1u) ? (uint16_t)(sample_count - 1u) : 1u;
|
||||
value = min_value + (span * (int32_t)sample_index) / (int32_t)denominator;
|
||||
}
|
||||
|
||||
if (value < AD9102_SRAM_RAMP_MIN)
|
||||
{
|
||||
value = AD9102_SRAM_RAMP_MIN;
|
||||
}
|
||||
else if (value > AD9102_SRAM_RAMP_MAX)
|
||||
{
|
||||
value = AD9102_SRAM_RAMP_MAX;
|
||||
}
|
||||
|
||||
ad9102_write_reg((uint16_t)(AD9102_REG_SRAM_DATA_BASE + sample_index),
|
||||
(uint16_t)(((uint16_t)((int16_t)value) & 0x3FFFu) << 2));
|
||||
}
|
||||
|
||||
ad9102_write_reg(AD9102_REG_PAT_STATUS, 0x0000u);
|
||||
}
|
||||
|
||||
void ad9102_init(void)
|
||||
{
|
||||
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(AD9102_RESET_GPIO_Port, AD9102_RESET_Pin, GPIO_PIN_RESET);
|
||||
|
||||
for (volatile uint32_t delay_counter = 0u; delay_counter < 1000u; ++delay_counter)
|
||||
{
|
||||
}
|
||||
|
||||
HAL_GPIO_WritePin(AD9102_RESET_GPIO_Port, AD9102_RESET_Pin, GPIO_PIN_SET);
|
||||
ad9102_write_reg_table(g_ad9102_example4_regval, AD9102_REG_COUNT);
|
||||
ad9102_write_reg(AD9102_REG_PAT_STATUS, 0x0000u);
|
||||
ad9102_write_reg(AD9102_REG_RAMUPDATE, 0x0001u);
|
||||
HAL_GPIO_WritePin(AD9102_TRIG_GPIO_Port, AD9102_TRIG_Pin, GPIO_PIN_SET);
|
||||
ad9102_reset_upload_state();
|
||||
}
|
||||
|
||||
void ad9102_stop_output(void)
|
||||
{
|
||||
ad9102_write_reg(AD9102_REG_PAT_STATUS, 0x0000u);
|
||||
HAL_GPIO_WritePin(AD9102_TRIG_GPIO_Port, AD9102_TRIG_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
uint16_t ad9102_apply_saw(uint8_t saw_type,
|
||||
uint8_t enabled,
|
||||
uint8_t saw_step,
|
||||
uint8_t pat_period_base,
|
||||
uint16_t pat_period)
|
||||
{
|
||||
uint16_t saw_config;
|
||||
uint16_t pat_timebase;
|
||||
|
||||
ad9102_reset_upload_state();
|
||||
|
||||
if (enabled == 0u)
|
||||
{
|
||||
ad9102_stop_output();
|
||||
return ad9102_read_reg(AD9102_REG_PAT_STATUS);
|
||||
}
|
||||
|
||||
if (saw_step == 0u)
|
||||
{
|
||||
saw_step = AD9102_SAW_STEP_DEFAULT;
|
||||
}
|
||||
else if (saw_step > 63u)
|
||||
{
|
||||
saw_step = 63u;
|
||||
}
|
||||
|
||||
if (pat_period == 0u)
|
||||
{
|
||||
pat_period = AD9102_PAT_PERIOD_DEFAULT;
|
||||
}
|
||||
|
||||
saw_config = (uint16_t)(((uint16_t)(saw_step & 0x3Fu) << 2) | ((uint16_t)(saw_type & 0x3u)));
|
||||
pat_timebase = (uint16_t)(((AD9102_PAT_TIMEBASE_HOLD_DEFAULT & 0x0Fu) << 8) |
|
||||
((pat_period_base & 0x0Fu) << 4) |
|
||||
(AD9102_START_DELAY_BASE_DEFAULT & 0x0Fu));
|
||||
|
||||
ad9102_write_reg(AD9102_REG_WAV_CONFIG, AD9102_EX4_WAV_CONFIG);
|
||||
ad9102_write_reg(AD9102_REG_SAW_CONFIG, saw_config);
|
||||
ad9102_write_reg(AD9102_REG_PAT_TIMEBASE, pat_timebase);
|
||||
ad9102_write_reg(AD9102_REG_PAT_PERIOD, pat_period);
|
||||
ad9102_write_reg(AD9102_REG_PAT_TYPE, 0x0000u);
|
||||
ad9102_start_output();
|
||||
|
||||
return ad9102_read_reg(AD9102_REG_PAT_STATUS);
|
||||
}
|
||||
|
||||
uint16_t ad9102_apply_generated_sram(uint8_t enabled,
|
||||
uint16_t sample_count,
|
||||
uint8_t hold_cycles,
|
||||
uint8_t triangle_mode,
|
||||
uint16_t amplitude)
|
||||
{
|
||||
ad9102_reset_upload_state();
|
||||
|
||||
if (sample_count == 0u)
|
||||
{
|
||||
sample_count = AD9102_SRAM_DEFAULT_SAMPLE_COUNT;
|
||||
}
|
||||
if (sample_count < 2u)
|
||||
{
|
||||
sample_count = 2u;
|
||||
}
|
||||
if (sample_count > AD9102_SRAM_MAX_SAMPLE_COUNT)
|
||||
{
|
||||
sample_count = AD9102_SRAM_MAX_SAMPLE_COUNT;
|
||||
}
|
||||
if (hold_cycles == 0u)
|
||||
{
|
||||
hold_cycles = AD9102_SRAM_DEFAULT_HOLD;
|
||||
}
|
||||
if (hold_cycles > 0x0Fu)
|
||||
{
|
||||
hold_cycles = 0x0Fu;
|
||||
}
|
||||
if (amplitude > AD9102_SRAM_DEFAULT_AMPLITUDE)
|
||||
{
|
||||
amplitude = AD9102_SRAM_DEFAULT_AMPLITUDE;
|
||||
}
|
||||
|
||||
ad9102_configure_sram_playback(sample_count, hold_cycles);
|
||||
ad9102_load_sram_ramp(sample_count, triangle_mode, amplitude);
|
||||
|
||||
if (enabled != 0u)
|
||||
{
|
||||
ad9102_start_output();
|
||||
}
|
||||
else
|
||||
{
|
||||
ad9102_stop_output();
|
||||
}
|
||||
|
||||
return ad9102_read_reg(AD9102_REG_PAT_STATUS);
|
||||
}
|
||||
|
||||
bool ad9102_begin_custom_upload(uint16_t sample_count)
|
||||
{
|
||||
if ((sample_count < 2u) || (sample_count > AD9102_SRAM_MAX_SAMPLE_COUNT))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ad9102_stop_output();
|
||||
ad9102_reset_upload_state();
|
||||
ad9102_configure_sram_playback(sample_count, AD9102_SRAM_DEFAULT_HOLD);
|
||||
ad9102_write_reg(AD9102_REG_PAT_STATUS, 0x0004u);
|
||||
|
||||
g_upload_state.expected_samples = sample_count;
|
||||
g_upload_state.written_samples = 0u;
|
||||
g_upload_state.active = 1u;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ad9102_write_custom_chunk(const uint16_t *samples, uint16_t chunk_count)
|
||||
{
|
||||
uint16_t index;
|
||||
|
||||
if ((samples == NULL) || (g_upload_state.active == 0u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ((chunk_count == 0u) || (chunk_count > AD9102_WAVE_MAX_CHUNK_SAMPLES))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (((uint32_t)g_upload_state.written_samples + (uint32_t)chunk_count) >
|
||||
(uint32_t)g_upload_state.expected_samples)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (index = 0u; index < chunk_count; ++index)
|
||||
{
|
||||
int16_t sample = (int16_t)samples[index];
|
||||
|
||||
if ((sample < AD9102_SRAM_RAMP_MIN) || (sample > AD9102_SRAM_RAMP_MAX))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ad9102_write_reg((uint16_t)(AD9102_REG_SRAM_DATA_BASE + g_upload_state.written_samples + index),
|
||||
(uint16_t)(((uint16_t)sample & 0x3FFFu) << 2));
|
||||
}
|
||||
|
||||
g_upload_state.written_samples = (uint16_t)(g_upload_state.written_samples + chunk_count);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t ad9102_commit_custom_upload(bool *out_ok)
|
||||
{
|
||||
uint16_t pat_status;
|
||||
|
||||
if (out_ok != NULL)
|
||||
{
|
||||
*out_ok = false;
|
||||
}
|
||||
|
||||
if ((g_upload_state.active == 0u) ||
|
||||
(g_upload_state.expected_samples < 2u) ||
|
||||
(g_upload_state.written_samples != g_upload_state.expected_samples))
|
||||
{
|
||||
ad9102_cancel_custom_upload();
|
||||
return ad9102_read_reg(AD9102_REG_PAT_STATUS);
|
||||
}
|
||||
|
||||
ad9102_write_reg(AD9102_REG_PAT_STATUS, 0x0000u);
|
||||
ad9102_write_reg(AD9102_REG_START_ADDR, 0x0000u);
|
||||
ad9102_write_reg(AD9102_REG_STOP_ADDR, (uint16_t)((g_upload_state.expected_samples - 1u) << 4));
|
||||
ad9102_write_reg(AD9102_REG_RAMUPDATE, 0x0001u);
|
||||
ad9102_start_output();
|
||||
pat_status = ad9102_read_reg(AD9102_REG_PAT_STATUS);
|
||||
|
||||
ad9102_reset_upload_state();
|
||||
if (out_ok != NULL)
|
||||
{
|
||||
*out_ok = true;
|
||||
}
|
||||
|
||||
return pat_status;
|
||||
}
|
||||
|
||||
void ad9102_cancel_custom_upload(void)
|
||||
{
|
||||
if (g_upload_state.active != 0u)
|
||||
{
|
||||
ad9102_stop_output();
|
||||
}
|
||||
|
||||
ad9102_reset_upload_state();
|
||||
}
|
||||
|
||||
uint8_t ad9102_check_saw_configuration(uint16_t pat_status,
|
||||
uint8_t expect_run,
|
||||
uint8_t saw_type,
|
||||
uint8_t saw_step,
|
||||
uint8_t pat_period_base,
|
||||
uint16_t pat_period)
|
||||
{
|
||||
uint16_t spiconfig = ad9102_read_reg(AD9102_REG_SPICONFIG);
|
||||
uint16_t power_config = ad9102_read_reg(AD9102_REG_POWERCONFIG);
|
||||
uint16_t clock_config = ad9102_read_reg(AD9102_REG_CLOCKCONFIG);
|
||||
uint16_t config_error = ad9102_read_reg(AD9102_REG_CFG_ERROR);
|
||||
uint16_t pat_timebase = (uint16_t)(((AD9102_PAT_TIMEBASE_HOLD_DEFAULT & 0x0Fu) << 8) |
|
||||
((pat_period_base & 0x0Fu) << 4) |
|
||||
(AD9102_START_DELAY_BASE_DEFAULT & 0x0Fu));
|
||||
uint16_t expected_saw;
|
||||
uint8_t ok = 1u;
|
||||
|
||||
if (saw_step == 0u)
|
||||
{
|
||||
saw_step = AD9102_SAW_STEP_DEFAULT;
|
||||
}
|
||||
if (saw_step > 63u)
|
||||
{
|
||||
saw_step = 63u;
|
||||
}
|
||||
if (pat_period == 0u)
|
||||
{
|
||||
pat_period = AD9102_PAT_PERIOD_DEFAULT;
|
||||
}
|
||||
|
||||
expected_saw = (uint16_t)(((uint16_t)(saw_step & 0x3Fu) << 2) | ((uint16_t)(saw_type & 0x3u)));
|
||||
|
||||
if (spiconfig != 0x0000u)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (power_config & ((1u << 8) | (1u << 7) | (1u << 6) | (1u << 5) | (1u << 3)))
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (clock_config & ((1u << 11) | (1u << 7) | (1u << 6) | (1u << 5)))
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (config_error & 0x003Fu)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if ((expect_run != 0u) && ((pat_status & AD9102_PAT_STATUS_RUN) == 0u))
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (ad9102_read_reg(AD9102_REG_WAV_CONFIG) != AD9102_EX4_WAV_CONFIG)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (ad9102_read_reg(AD9102_REG_PAT_TIMEBASE) != pat_timebase)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (ad9102_read_reg(AD9102_REG_PAT_PERIOD) != pat_period)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (ad9102_read_reg(AD9102_REG_PAT_TYPE) != 0x0000u)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (ad9102_read_reg(AD9102_REG_SAW_CONFIG) != expected_saw)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
|
||||
return (ok != 0u) ? 0u : 1u;
|
||||
}
|
||||
|
||||
uint8_t ad9102_check_sram_configuration(uint16_t pat_status,
|
||||
uint8_t expect_run,
|
||||
uint16_t sample_count,
|
||||
uint8_t hold_cycles)
|
||||
{
|
||||
uint16_t spiconfig = ad9102_read_reg(AD9102_REG_SPICONFIG);
|
||||
uint16_t power_config = ad9102_read_reg(AD9102_REG_POWERCONFIG);
|
||||
uint16_t clock_config = ad9102_read_reg(AD9102_REG_CLOCKCONFIG);
|
||||
uint16_t config_error = ad9102_read_reg(AD9102_REG_CFG_ERROR);
|
||||
uint16_t pat_timebase;
|
||||
uint32_t pat_period;
|
||||
uint16_t stop_address;
|
||||
uint8_t ok = 1u;
|
||||
|
||||
if (sample_count == 0u)
|
||||
{
|
||||
sample_count = AD9102_SRAM_DEFAULT_SAMPLE_COUNT;
|
||||
}
|
||||
if (sample_count < 2u)
|
||||
{
|
||||
sample_count = 2u;
|
||||
}
|
||||
if (sample_count > AD9102_SRAM_MAX_SAMPLE_COUNT)
|
||||
{
|
||||
sample_count = AD9102_SRAM_MAX_SAMPLE_COUNT;
|
||||
}
|
||||
if (hold_cycles == 0u)
|
||||
{
|
||||
hold_cycles = AD9102_SRAM_DEFAULT_HOLD;
|
||||
}
|
||||
if (hold_cycles > 0x0Fu)
|
||||
{
|
||||
hold_cycles = 0x0Fu;
|
||||
}
|
||||
|
||||
pat_timebase = (uint16_t)(((uint16_t)(hold_cycles & 0x0Fu) << 8) |
|
||||
((AD9102_SRAM_PAT_PERIOD_BASE_DEFAULT & 0x0Fu) << 4) |
|
||||
(AD9102_SRAM_START_DELAY_BASE_DEFAULT & 0x0Fu));
|
||||
pat_period = (uint32_t)sample_count * (uint32_t)(hold_cycles & 0x0Fu);
|
||||
if (pat_period == 0u)
|
||||
{
|
||||
pat_period = sample_count;
|
||||
}
|
||||
if (pat_period > 0xFFFFu)
|
||||
{
|
||||
pat_period = 0xFFFFu;
|
||||
}
|
||||
|
||||
stop_address = (uint16_t)((sample_count - 1u) << 4);
|
||||
|
||||
if (spiconfig != 0x0000u)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (power_config & ((1u << 8) | (1u << 7) | (1u << 6) | (1u << 5) | (1u << 3)))
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (clock_config & ((1u << 11) | (1u << 7) | (1u << 6) | (1u << 5)))
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (config_error & 0x003Fu)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if ((expect_run != 0u) && ((pat_status & AD9102_PAT_STATUS_RUN) == 0u))
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (ad9102_read_reg(AD9102_REG_WAV_CONFIG) != AD9102_EX2_WAV_CONFIG)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (ad9102_read_reg(AD9102_REG_PAT_TIMEBASE) != pat_timebase)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (ad9102_read_reg(AD9102_REG_PAT_PERIOD) != (uint16_t)pat_period)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (ad9102_read_reg(AD9102_REG_PAT_TYPE) != 0x0000u)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (ad9102_read_reg(AD9102_REG_START_ADDR) != 0x0000u)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (ad9102_read_reg(AD9102_REG_STOP_ADDR) != stop_address)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
if (ad9102_read_reg(AD9102_REG_DAC_PAT) != AD9102_EX2_DAC_PAT)
|
||||
{
|
||||
ok = 0u;
|
||||
}
|
||||
|
||||
return (ok != 0u) ? 0u : 1u;
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
/**
|
||||
* @file ad9102_device.h
|
||||
* @brief AD9102 waveform-generation device driver.
|
||||
*
|
||||
* Architectural note:
|
||||
* The driver owns all AD9102 register tables and safe mode switching rules.
|
||||
* High-level services describe *what* waveform to apply, while this module
|
||||
* owns the register-level details of *how* to enter, verify, and leave each
|
||||
* mode without cross-coupling to UART or storage logic.
|
||||
*/
|
||||
|
||||
#ifndef AD9102_DEVICE_H
|
||||
#define AD9102_DEVICE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "app_types.h"
|
||||
|
||||
#define AD9102_SRAM_DEFAULT_HOLD 1u
|
||||
#define AD9102_SRAM_DEFAULT_AMPLITUDE 8191u
|
||||
#define AD9102_SRAM_DEFAULT_SAMPLE_COUNT 16u
|
||||
#define AD9102_SRAM_MAX_SAMPLE_COUNT 4096u
|
||||
|
||||
void ad9102_init(void);
|
||||
void ad9102_stop_output(void);
|
||||
uint16_t ad9102_apply_saw(uint8_t saw_type,
|
||||
uint8_t enabled,
|
||||
uint8_t saw_step,
|
||||
uint8_t pat_period_base,
|
||||
uint16_t pat_period);
|
||||
uint16_t ad9102_apply_generated_sram(uint8_t enabled,
|
||||
uint16_t sample_count,
|
||||
uint8_t hold_cycles,
|
||||
uint8_t triangle_mode,
|
||||
uint16_t amplitude);
|
||||
bool ad9102_begin_custom_upload(uint16_t sample_count);
|
||||
bool ad9102_write_custom_chunk(const uint16_t *samples, uint16_t chunk_count);
|
||||
uint16_t ad9102_commit_custom_upload(bool *out_ok);
|
||||
void ad9102_cancel_custom_upload(void);
|
||||
uint8_t ad9102_check_saw_configuration(uint16_t pat_status,
|
||||
uint8_t expect_run,
|
||||
uint8_t saw_type,
|
||||
uint8_t saw_step,
|
||||
uint8_t pat_period_base,
|
||||
uint16_t pat_period);
|
||||
uint8_t ad9102_check_sram_configuration(uint16_t pat_status,
|
||||
uint8_t expect_run,
|
||||
uint16_t sample_count,
|
||||
uint8_t hold_cycles);
|
||||
|
||||
#endif /* AD9102_DEVICE_H */
|
||||
@ -1,64 +0,0 @@
|
||||
/**
|
||||
* @file ad9833_device.c
|
||||
* @brief AD9833 waveform-generator control helpers.
|
||||
*/
|
||||
|
||||
#include "ad9833_device.h"
|
||||
|
||||
#include "board_io.h"
|
||||
#include "main.h"
|
||||
|
||||
static void ad9833_write_word(uint16_t word)
|
||||
{
|
||||
uint32_t timeout = 0u;
|
||||
|
||||
board_io_configure_spi2_mode(LL_SPI_POLARITY_HIGH, LL_SPI_PHASE_1EDGE);
|
||||
|
||||
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(DAC_LD1_CS_GPIO_Port, DAC_LD1_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(DAC_TEC1_CS_GPIO_Port, DAC_TEC1_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(AD9833_CS_GPIO_Port, AD9833_CS_Pin, GPIO_PIN_RESET);
|
||||
|
||||
while ((!LL_SPI_IsActiveFlag_TXE(SPI2)) && (timeout++ < 1000u))
|
||||
{
|
||||
}
|
||||
LL_SPI_TransmitData16(SPI2, word);
|
||||
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI2)) && (timeout++ < 1000u))
|
||||
{
|
||||
}
|
||||
(void)SPI2->DR;
|
||||
|
||||
HAL_GPIO_WritePin(AD9833_CS_GPIO_Port, AD9833_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
void ad9833_apply(uint8_t enabled, uint8_t triangle_mode, uint32_t frequency_word)
|
||||
{
|
||||
uint16_t control = 0x2000u;
|
||||
uint16_t lsw;
|
||||
uint16_t msw;
|
||||
|
||||
if (triangle_mode != 0u)
|
||||
{
|
||||
control |= 0x0002u;
|
||||
}
|
||||
|
||||
control |= 0x0100u;
|
||||
|
||||
frequency_word &= 0x0FFFFFFFu;
|
||||
lsw = (uint16_t)(0x4000u | (frequency_word & 0x3FFFu));
|
||||
msw = (uint16_t)(0x4000u | ((frequency_word >> 14) & 0x3FFFu));
|
||||
|
||||
ad9833_write_word(control);
|
||||
ad9833_write_word(lsw);
|
||||
ad9833_write_word(msw);
|
||||
ad9833_write_word(0xC000u);
|
||||
|
||||
if (enabled != 0u)
|
||||
{
|
||||
control &= (uint16_t)(~0x0100u);
|
||||
}
|
||||
|
||||
ad9833_write_word(control);
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
/**
|
||||
* @file ad9833_device.h
|
||||
* @brief AD9833 waveform generator control helpers.
|
||||
*/
|
||||
|
||||
#ifndef AD9833_DEVICE_H
|
||||
#define AD9833_DEVICE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void ad9833_apply(uint8_t enabled, uint8_t triangle_mode, uint32_t frequency_word);
|
||||
|
||||
#endif /* AD9833_DEVICE_H */
|
||||
@ -1,183 +0,0 @@
|
||||
/**
|
||||
* @file adc_mux.c
|
||||
* @brief External photodiode ADC and internal STM32 ADC helpers.
|
||||
*/
|
||||
|
||||
#include "adc_mux.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "board_handles.h"
|
||||
#include "main.h"
|
||||
|
||||
uint16_t adc_mux_read_external_channel(uint8_t channel_index)
|
||||
{
|
||||
uint16_t result = 0u;
|
||||
uint32_t delay_counter;
|
||||
|
||||
HAL_GPIO_WritePin(SPI4_CNV_GPIO_Port, SPI4_CNV_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(SPI5_CNV_GPIO_Port, SPI5_CNV_Pin, GPIO_PIN_RESET);
|
||||
for (delay_counter = 0u; delay_counter < 500u; ++delay_counter)
|
||||
{
|
||||
}
|
||||
|
||||
HAL_GPIO_WritePin(SPI4_CNV_GPIO_Port, SPI4_CNV_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(SPI5_CNV_GPIO_Port, SPI5_CNV_Pin, GPIO_PIN_SET);
|
||||
for (delay_counter = 0u; delay_counter < 500u; ++delay_counter)
|
||||
{
|
||||
}
|
||||
|
||||
if (channel_index == 1u)
|
||||
{
|
||||
HAL_GPIO_WritePin(ADC_ThrLD1_CS_GPIO_Port, ADC_ThrLD1_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(ADC_MPD1_CS_GPIO_Port, ADC_MPD1_CS_Pin, GPIO_PIN_RESET);
|
||||
for (delay_counter = 0u; delay_counter < 500u; ++delay_counter)
|
||||
{
|
||||
}
|
||||
|
||||
LL_SPI_Enable(SPI4);
|
||||
delay_counter = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI4)) && (delay_counter <= 1000u))
|
||||
{
|
||||
++delay_counter;
|
||||
}
|
||||
LL_SPI_Disable(SPI4);
|
||||
while (delay_counter < 500u)
|
||||
{
|
||||
++delay_counter;
|
||||
}
|
||||
HAL_GPIO_WritePin(ADC_MPD1_CS_GPIO_Port, ADC_MPD1_CS_Pin, GPIO_PIN_SET);
|
||||
result = LL_SPI_ReceiveData16(SPI4);
|
||||
}
|
||||
else if (channel_index == 2u)
|
||||
{
|
||||
HAL_GPIO_WritePin(ADC_ThrLD2_CS_GPIO_Port, ADC_ThrLD2_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(ADC_MPD2_CS_GPIO_Port, ADC_MPD2_CS_Pin, GPIO_PIN_RESET);
|
||||
for (delay_counter = 0u; delay_counter < 500u; ++delay_counter)
|
||||
{
|
||||
}
|
||||
|
||||
LL_SPI_Enable(SPI5);
|
||||
delay_counter = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI5)) && (delay_counter <= 1000u))
|
||||
{
|
||||
++delay_counter;
|
||||
}
|
||||
LL_SPI_Disable(SPI5);
|
||||
while (delay_counter < 500u)
|
||||
{
|
||||
++delay_counter;
|
||||
}
|
||||
HAL_GPIO_WritePin(ADC_MPD2_CS_GPIO_Port, ADC_MPD2_CS_Pin, GPIO_PIN_SET);
|
||||
result = LL_SPI_ReceiveData16(SPI5);
|
||||
}
|
||||
else if (channel_index == 3u)
|
||||
{
|
||||
HAL_GPIO_WritePin(ADC_MPD1_CS_GPIO_Port, ADC_MPD1_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(ADC_ThrLD1_CS_GPIO_Port, ADC_ThrLD1_CS_Pin, GPIO_PIN_RESET);
|
||||
for (delay_counter = 0u; delay_counter < 500u; ++delay_counter)
|
||||
{
|
||||
}
|
||||
|
||||
LL_SPI_Enable(SPI4);
|
||||
delay_counter = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI4)) && (delay_counter <= 1000u))
|
||||
{
|
||||
++delay_counter;
|
||||
}
|
||||
LL_SPI_Disable(SPI4);
|
||||
while (delay_counter < 500u)
|
||||
{
|
||||
++delay_counter;
|
||||
}
|
||||
HAL_GPIO_WritePin(ADC_ThrLD1_CS_GPIO_Port, ADC_ThrLD1_CS_Pin, GPIO_PIN_SET);
|
||||
result = LL_SPI_ReceiveData16(SPI4);
|
||||
}
|
||||
else if (channel_index == 4u)
|
||||
{
|
||||
HAL_GPIO_WritePin(ADC_MPD2_CS_GPIO_Port, ADC_MPD2_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(ADC_ThrLD2_CS_GPIO_Port, ADC_ThrLD2_CS_Pin, GPIO_PIN_RESET);
|
||||
for (delay_counter = 0u; delay_counter < 500u; ++delay_counter)
|
||||
{
|
||||
}
|
||||
|
||||
LL_SPI_Enable(SPI5);
|
||||
delay_counter = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI5)) && (delay_counter <= 1000u))
|
||||
{
|
||||
++delay_counter;
|
||||
}
|
||||
LL_SPI_Disable(SPI5);
|
||||
while (delay_counter < 500u)
|
||||
{
|
||||
++delay_counter;
|
||||
}
|
||||
HAL_GPIO_WritePin(ADC_ThrLD2_CS_GPIO_Port, ADC_ThrLD2_CS_Pin, GPIO_PIN_SET);
|
||||
result = LL_SPI_ReceiveData16(SPI5);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool adc_mux_read_sequence(ADC_HandleTypeDef *hadc, uint16_t *output_buffer, uint8_t sample_count)
|
||||
{
|
||||
uint8_t sample_index;
|
||||
|
||||
if ((hadc == NULL) || (output_buffer == NULL) || (sample_count == 0u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HAL_ADC_Start(hadc) != HAL_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (sample_index = 0u; sample_index < sample_count; ++sample_index)
|
||||
{
|
||||
if (HAL_ADC_PollForConversion(hadc, 100u) != HAL_OK)
|
||||
{
|
||||
(void)HAL_ADC_Stop(hadc);
|
||||
return false;
|
||||
}
|
||||
|
||||
output_buffer[sample_index] = (uint16_t)HAL_ADC_GetValue(hadc);
|
||||
}
|
||||
|
||||
(void)HAL_ADC_Stop(hadc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool adc_mux_capture_internal_telemetry(adc_internal_telemetry_t *telemetry)
|
||||
{
|
||||
uint16_t adc1_samples[5];
|
||||
uint16_t adc3_samples[3];
|
||||
|
||||
if (telemetry == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(telemetry, 0, sizeof(*telemetry));
|
||||
|
||||
if (!adc_mux_read_sequence(&hadc1, adc1_samples, 5u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!adc_mux_read_sequence(&hadc3, adc3_samples, 3u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
telemetry->external_temperature_1_raw = adc1_samples[0];
|
||||
telemetry->external_temperature_2_raw = adc1_samples[1];
|
||||
telemetry->rail_3v3_raw = adc1_samples[2];
|
||||
telemetry->rail_5v1_raw = adc1_samples[3];
|
||||
telemetry->rail_5v2_raw = adc1_samples[4];
|
||||
telemetry->input_pf3_raw = adc3_samples[0];
|
||||
telemetry->input_pf4_raw = adc3_samples[1];
|
||||
telemetry->rail_7v0_raw = adc3_samples[2];
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
/**
|
||||
* @file adc_mux.h
|
||||
* @brief Helpers for external photodiode ADCs and internal STM32 ADC channels.
|
||||
*/
|
||||
|
||||
#ifndef ADC_MUX_H
|
||||
#define ADC_MUX_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Snapshot of all internal STM32 ADC channels exported through telemetry.
|
||||
*
|
||||
* The firmware keeps the UART telemetry frame fixed at 30 bytes, so the host
|
||||
* and the board agree on a stable slot order. These fields are captured from
|
||||
* the MCU ADC peripherals once per telemetry refresh and then packed into that
|
||||
* frame by the application core.
|
||||
*/
|
||||
typedef struct adc_internal_telemetry_t {
|
||||
/** @brief Raw 12-bit code for external temperature sensor channel 1. */
|
||||
uint16_t external_temperature_1_raw;
|
||||
/** @brief Raw 12-bit code for external temperature sensor channel 2. */
|
||||
uint16_t external_temperature_2_raw;
|
||||
/** @brief Raw 12-bit code for the monitored 3.3V rail. */
|
||||
uint16_t rail_3v3_raw;
|
||||
/** @brief Raw 12-bit code for the monitored 5V1 rail. */
|
||||
uint16_t rail_5v1_raw;
|
||||
/** @brief Raw 12-bit code for the monitored 5V2 rail. */
|
||||
uint16_t rail_5v2_raw;
|
||||
/** @brief Raw 12-bit code read from free analog input PF3 / ADC3_IN9. */
|
||||
uint16_t input_pf3_raw;
|
||||
/** @brief Raw 12-bit code read from free analog input PF4 / ADC3_IN14. */
|
||||
uint16_t input_pf4_raw;
|
||||
/** @brief Raw 12-bit code for the monitored 7V rail. */
|
||||
uint16_t rail_7v0_raw;
|
||||
} adc_internal_telemetry_t;
|
||||
|
||||
uint16_t adc_mux_read_external_channel(uint8_t channel_index);
|
||||
bool adc_mux_capture_internal_telemetry(adc_internal_telemetry_t *telemetry);
|
||||
|
||||
#endif /* ADC_MUX_H */
|
||||
@ -1,22 +0,0 @@
|
||||
/**
|
||||
* @file board_handles.h
|
||||
* @brief Extern declarations for CubeMX-generated peripheral handles.
|
||||
*
|
||||
* Architectural note:
|
||||
* Device and service modules depend on hardware handles owned by `Src/main.c`.
|
||||
* This header isolates those extern declarations so the App layer never has to
|
||||
* pull application types back into the CubeMX-generated file.
|
||||
*/
|
||||
|
||||
#ifndef BOARD_HANDLES_H
|
||||
#define BOARD_HANDLES_H
|
||||
|
||||
#include "main.h"
|
||||
|
||||
extern ADC_HandleTypeDef hadc1;
|
||||
extern ADC_HandleTypeDef hadc3;
|
||||
extern SD_HandleTypeDef hsd1;
|
||||
extern TIM_HandleTypeDef htim1;
|
||||
extern UART_HandleTypeDef huart8;
|
||||
|
||||
#endif /* BOARD_HANDLES_H */
|
||||
@ -1,257 +0,0 @@
|
||||
/**
|
||||
* @file board_io.c
|
||||
* @brief Board-specific GPIO and shared low-level control helpers.
|
||||
*/
|
||||
|
||||
#include "board_io.h"
|
||||
|
||||
#define UI_LCD_CONTRAST_PWM_FREQUENCY_HZ 20000u
|
||||
#define UI_LCD_CONTRAST_PWM_PERIOD_COUNTS 1000u
|
||||
#define UI_LCD_CONTRAST_PWM_DUTY_PERMILLE 300u
|
||||
|
||||
static TIM_HandleTypeDef g_ui_lcd_contrast_pwm_timer;
|
||||
|
||||
static uint32_t board_io_get_apb1_timer_clock_hz(void);
|
||||
static void board_io_init_lcd_contrast_pwm(void);
|
||||
|
||||
void board_io_enable_uart_rx_irq(void)
|
||||
{
|
||||
LL_USART_EnableIT_PE(USART1);
|
||||
LL_USART_EnableIT_RXNE(USART1);
|
||||
LL_USART_EnableIT_ERROR(USART1);
|
||||
NVIC_SetPriority(USART1_IRQn, 0);
|
||||
NVIC_EnableIRQ(USART1_IRQn);
|
||||
}
|
||||
|
||||
void board_io_init_standalone_ui(void)
|
||||
{
|
||||
GPIO_InitTypeDef gpio_init = {0};
|
||||
|
||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
|
||||
HAL_GPIO_WritePin(UI_LCD_RS_GPIO_Port,
|
||||
UI_LCD_RS_Pin | UI_LCD_E_Pin | UI_LCD_D4_Pin | UI_LCD_D5_Pin | UI_LCD_D6_Pin | UI_LCD_D7_Pin,
|
||||
GPIO_PIN_RESET);
|
||||
|
||||
/*
|
||||
* A fixed contrast pin is only a compromise until a potentiometer is
|
||||
* added. Driving V0 low is the safest default for HD44780/SPLC780D-style
|
||||
* modules because it makes characters visible instead of appearing blank.
|
||||
*/
|
||||
HAL_GPIO_WritePin(UI_LCD_V0_REF_GPIO_Port, UI_LCD_V0_REF_Pin, GPIO_PIN_RESET);
|
||||
|
||||
gpio_init.Pin = UI_LCD_RS_Pin | UI_LCD_E_Pin | UI_LCD_D4_Pin | UI_LCD_D5_Pin | UI_LCD_D6_Pin | UI_LCD_D7_Pin;
|
||||
gpio_init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
gpio_init.Pull = GPIO_NOPULL;
|
||||
gpio_init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOG, &gpio_init);
|
||||
|
||||
gpio_init.Pin = UI_LCD_V0_REF_Pin;
|
||||
gpio_init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
gpio_init.Pull = GPIO_NOPULL;
|
||||
gpio_init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(UI_LCD_V0_REF_GPIO_Port, &gpio_init);
|
||||
|
||||
gpio_init.Pin = UI_BUTTON_Pin;
|
||||
gpio_init.Mode = GPIO_MODE_INPUT;
|
||||
gpio_init.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(UI_BUTTON_GPIO_Port, &gpio_init);
|
||||
|
||||
board_io_init_lcd_contrast_pwm();
|
||||
}
|
||||
|
||||
static uint32_t board_io_get_apb1_timer_clock_hz(void)
|
||||
{
|
||||
uint32_t pclk1_hz = HAL_RCC_GetPCLK1Freq();
|
||||
|
||||
if ((RCC->CFGR & RCC_CFGR_PPRE1) == RCC_CFGR_PPRE1_DIV1)
|
||||
{
|
||||
return pclk1_hz;
|
||||
}
|
||||
|
||||
return pclk1_hz * 2u;
|
||||
}
|
||||
|
||||
static void board_io_init_lcd_contrast_pwm(void)
|
||||
{
|
||||
GPIO_InitTypeDef gpio_init = {0};
|
||||
TIM_OC_InitTypeDef pwm_channel = {0};
|
||||
uint32_t timer_clock_hz = board_io_get_apb1_timer_clock_hz();
|
||||
uint32_t prescaler_divisor = timer_clock_hz / (UI_LCD_CONTRAST_PWM_FREQUENCY_HZ * UI_LCD_CONTRAST_PWM_PERIOD_COUNTS);
|
||||
uint32_t pulse_counts = ((UI_LCD_CONTRAST_PWM_PERIOD_COUNTS * UI_LCD_CONTRAST_PWM_DUTY_PERMILLE) + 999u) / 1000u;
|
||||
|
||||
if (prescaler_divisor == 0u)
|
||||
{
|
||||
prescaler_divisor = 1u;
|
||||
}
|
||||
|
||||
if (pulse_counts >= UI_LCD_CONTRAST_PWM_PERIOD_COUNTS)
|
||||
{
|
||||
pulse_counts = UI_LCD_CONTRAST_PWM_PERIOD_COUNTS - 1u;
|
||||
}
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_TIM4_CLK_ENABLE();
|
||||
|
||||
/*
|
||||
* This PWM output is intended for the LCD contrast input (V0) through a
|
||||
* simple RC low-pass filter. Keeping it local to board_io.c avoids
|
||||
* spreading board wiring assumptions into higher-level UI code.
|
||||
*/
|
||||
gpio_init.Pin = UI_LCD_CONTRAST_PWM_Pin;
|
||||
gpio_init.Mode = GPIO_MODE_AF_PP;
|
||||
gpio_init.Pull = GPIO_NOPULL;
|
||||
gpio_init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
gpio_init.Alternate = GPIO_AF2_TIM4;
|
||||
HAL_GPIO_Init(UI_LCD_CONTRAST_PWM_GPIO_Port, &gpio_init);
|
||||
|
||||
g_ui_lcd_contrast_pwm_timer.Instance = TIM4;
|
||||
g_ui_lcd_contrast_pwm_timer.Init.Prescaler = (uint32_t)(prescaler_divisor - 1u);
|
||||
g_ui_lcd_contrast_pwm_timer.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
g_ui_lcd_contrast_pwm_timer.Init.Period = UI_LCD_CONTRAST_PWM_PERIOD_COUNTS - 1u;
|
||||
g_ui_lcd_contrast_pwm_timer.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
g_ui_lcd_contrast_pwm_timer.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
|
||||
if (HAL_TIM_PWM_Init(&g_ui_lcd_contrast_pwm_timer) != HAL_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pwm_channel.OCMode = TIM_OCMODE_PWM1;
|
||||
pwm_channel.Pulse = pulse_counts;
|
||||
pwm_channel.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
pwm_channel.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
|
||||
if (HAL_TIM_PWM_ConfigChannel(&g_ui_lcd_contrast_pwm_timer, &pwm_channel, TIM_CHANNEL_3) != HAL_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
(void)HAL_TIM_PWM_Start(&g_ui_lcd_contrast_pwm_timer, TIM_CHANNEL_3);
|
||||
}
|
||||
|
||||
void board_io_reset_runtime_outputs(void)
|
||||
{
|
||||
HAL_GPIO_WritePin(EN_5V1_GPIO_Port, EN_5V1_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(EN_5V2_GPIO_Port, EN_5V2_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(LD1_EN_GPIO_Port, LD1_EN_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(LD2_EN_GPIO_Port, LD2_EN_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(REF0_EN_GPIO_Port, REF0_EN_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(REF2_ON_GPIO_Port, REF2_ON_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(TECEN1_GPIO_Port, TECEN1_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(TECEN2_GPIO_Port, TECEN2_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(TEC1_PD_GPIO_Port, TEC1_PD_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(TEC2_PD_GPIO_Port, TEC2_PD_Pin, GPIO_PIN_RESET);
|
||||
|
||||
HAL_GPIO_WritePin(ADC_MPD1_CS_GPIO_Port, ADC_MPD1_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(ADC_MPD2_CS_GPIO_Port, ADC_MPD2_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(SPI4_CNV_GPIO_Port, SPI4_CNV_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(SPI5_CNV_GPIO_Port, SPI5_CNV_Pin, GPIO_PIN_SET);
|
||||
|
||||
HAL_GPIO_WritePin(DAC_LD1_CS_GPIO_Port, DAC_LD1_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(DAC_LD2_CS_GPIO_Port, DAC_LD2_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(DAC_TEC1_CS_GPIO_Port, DAC_TEC1_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(DAC_TEC2_CS_GPIO_Port, DAC_TEC2_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(AD9833_CS_GPIO_Port, AD9833_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
void board_io_configure_spi2_mode(uint32_t polarity, uint32_t phase)
|
||||
{
|
||||
if (LL_SPI_IsEnabled(SPI2))
|
||||
{
|
||||
LL_SPI_Disable(SPI2);
|
||||
}
|
||||
|
||||
LL_SPI_SetClockPolarity(SPI2, polarity);
|
||||
LL_SPI_SetClockPhase(SPI2, phase);
|
||||
|
||||
if (!LL_SPI_IsEnabled(SPI2))
|
||||
{
|
||||
LL_SPI_Enable(SPI2);
|
||||
}
|
||||
}
|
||||
|
||||
bool board_io_is_usb_connected(void)
|
||||
{
|
||||
return HAL_GPIO_ReadPin(USB_FLAG_GPIO_Port, USB_FLAG_Pin) == GPIO_PIN_SET;
|
||||
}
|
||||
|
||||
bool board_io_is_sd_card_present(void)
|
||||
{
|
||||
return HAL_GPIO_ReadPin(SDMMC1_EN_GPIO_Port, SDMMC1_EN_Pin) == GPIO_PIN_RESET;
|
||||
}
|
||||
|
||||
bool board_io_is_standalone_ui_button_pressed(void)
|
||||
{
|
||||
return HAL_GPIO_ReadPin(UI_BUTTON_GPIO_Port, UI_BUTTON_Pin) == GPIO_PIN_RESET;
|
||||
}
|
||||
|
||||
void board_io_set_supply_enabled(uint8_t supply_index, bool enabled)
|
||||
{
|
||||
GPIO_PinState pin_state = enabled ? GPIO_PIN_SET : GPIO_PIN_RESET;
|
||||
|
||||
if (supply_index == 1u)
|
||||
{
|
||||
HAL_GPIO_WritePin(EN_5V1_GPIO_Port, EN_5V1_Pin, pin_state);
|
||||
}
|
||||
else if (supply_index == 2u)
|
||||
{
|
||||
HAL_GPIO_WritePin(EN_5V2_GPIO_Port, EN_5V2_Pin, pin_state);
|
||||
}
|
||||
}
|
||||
|
||||
void board_io_set_laser_enabled(uint8_t laser_index, bool enabled)
|
||||
{
|
||||
GPIO_PinState pin_state = enabled ? GPIO_PIN_SET : GPIO_PIN_RESET;
|
||||
|
||||
if (laser_index == 1u)
|
||||
{
|
||||
HAL_GPIO_WritePin(LD1_EN_GPIO_Port, LD1_EN_Pin, pin_state);
|
||||
}
|
||||
else if (laser_index == 2u)
|
||||
{
|
||||
HAL_GPIO_WritePin(LD2_EN_GPIO_Port, LD2_EN_Pin, pin_state);
|
||||
}
|
||||
}
|
||||
|
||||
void board_io_set_reference_enabled(uint8_t reference_index, bool enabled)
|
||||
{
|
||||
GPIO_PinState pin_state = enabled ? GPIO_PIN_SET : GPIO_PIN_RESET;
|
||||
|
||||
if (reference_index == 1u)
|
||||
{
|
||||
HAL_GPIO_WritePin(REF0_EN_GPIO_Port, REF0_EN_Pin, pin_state);
|
||||
}
|
||||
else if (reference_index == 2u)
|
||||
{
|
||||
HAL_GPIO_WritePin(REF2_ON_GPIO_Port, REF2_ON_Pin, pin_state);
|
||||
}
|
||||
}
|
||||
|
||||
void board_io_set_tec_channel_enabled(uint8_t tec_index, bool enabled)
|
||||
{
|
||||
GPIO_PinState pin_state = enabled ? GPIO_PIN_SET : GPIO_PIN_RESET;
|
||||
|
||||
if (tec_index == 1u)
|
||||
{
|
||||
HAL_GPIO_WritePin(TEC1_PD_GPIO_Port, TEC1_PD_Pin, pin_state);
|
||||
HAL_GPIO_WritePin(TECEN1_GPIO_Port, TECEN1_Pin, pin_state);
|
||||
}
|
||||
else if (tec_index == 2u)
|
||||
{
|
||||
HAL_GPIO_WritePin(TEC2_PD_GPIO_Port, TEC2_PD_Pin, pin_state);
|
||||
HAL_GPIO_WritePin(TECEN2_GPIO_Port, TECEN2_Pin, pin_state);
|
||||
}
|
||||
}
|
||||
|
||||
void board_io_write_signal(GPIO_TypeDef *port, uint16_t pin, bool level_high)
|
||||
{
|
||||
HAL_GPIO_WritePin(port, pin, level_high ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
void board_io_toggle_debug_pin(void)
|
||||
{
|
||||
HAL_GPIO_TogglePin(TEST_01_GPIO_Port, TEST_01_Pin);
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
/**
|
||||
* @file board_io.h
|
||||
* @brief Board-specific GPIO and low-level control helpers.
|
||||
*
|
||||
* Architectural note:
|
||||
* This module groups direct GPIO manipulations that are shared across several
|
||||
* devices and services. Doing so keeps register-driving code localised and
|
||||
* prevents high-level services from depending on scattered pin knowledge.
|
||||
*/
|
||||
|
||||
#ifndef BOARD_IO_H
|
||||
#define BOARD_IO_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "main.h"
|
||||
|
||||
void board_io_enable_uart_rx_irq(void);
|
||||
void board_io_init_standalone_ui(void);
|
||||
void board_io_reset_runtime_outputs(void);
|
||||
void board_io_configure_spi2_mode(uint32_t polarity, uint32_t phase);
|
||||
bool board_io_is_usb_connected(void);
|
||||
bool board_io_is_sd_card_present(void);
|
||||
bool board_io_is_standalone_ui_button_pressed(void);
|
||||
void board_io_set_supply_enabled(uint8_t supply_index, bool enabled);
|
||||
void board_io_set_laser_enabled(uint8_t laser_index, bool enabled);
|
||||
void board_io_set_reference_enabled(uint8_t reference_index, bool enabled);
|
||||
void board_io_set_tec_channel_enabled(uint8_t tec_index, bool enabled);
|
||||
void board_io_toggle_debug_pin(void);
|
||||
void board_io_write_signal(GPIO_TypeDef *port, uint16_t pin, bool level_high);
|
||||
|
||||
#endif /* BOARD_IO_H */
|
||||
@ -1,84 +0,0 @@
|
||||
/**
|
||||
* @file ds1809_device.c
|
||||
* @brief DS1809 pulse-based control helper.
|
||||
*/
|
||||
|
||||
#include "ds1809_device.h"
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define DS1809_POSITION_COUNT 64u
|
||||
#define DS1809_RESET_DOWN_PULSE_COUNT 80u
|
||||
#define DS1809_CPU_PULSE_WIDTH_MS 8u
|
||||
#define DS1809_CPU_INTER_PULSE_HIGH_MS 8u
|
||||
#define DS1809_CONTROL_PORT_READY_DELAY_MS 500u
|
||||
|
||||
static void ds1809_drive_idle_high(void)
|
||||
{
|
||||
HAL_GPIO_WritePin(DS1809_UC_GPIO_Port, DS1809_UC_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(DS1809_DC_GPIO_Port, DS1809_DC_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
static void ds1809_pulse_direction(uint8_t increment,
|
||||
uint8_t decrement,
|
||||
uint16_t count,
|
||||
uint16_t low_time_ms,
|
||||
uint16_t high_time_ms)
|
||||
{
|
||||
uint16_t pulse_index;
|
||||
|
||||
if ((count == 0u) || ((increment == 0u) && (decrement == 0u)))
|
||||
{
|
||||
ds1809_drive_idle_high();
|
||||
return;
|
||||
}
|
||||
|
||||
ds1809_drive_idle_high();
|
||||
|
||||
for (pulse_index = 0u; pulse_index < count; ++pulse_index)
|
||||
{
|
||||
if (increment != 0u)
|
||||
{
|
||||
HAL_GPIO_WritePin(DS1809_UC_GPIO_Port, DS1809_UC_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
if (decrement != 0u)
|
||||
{
|
||||
HAL_GPIO_WritePin(DS1809_DC_GPIO_Port, DS1809_DC_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
HAL_Delay(low_time_ms);
|
||||
ds1809_drive_idle_high();
|
||||
HAL_Delay(high_time_ms);
|
||||
}
|
||||
}
|
||||
|
||||
void ds1809_pulse(uint8_t increment, uint8_t decrement, uint16_t count, uint16_t pulse_ms)
|
||||
{
|
||||
if (pulse_ms < DS1809_CPU_PULSE_WIDTH_MS)
|
||||
{
|
||||
pulse_ms = DS1809_CPU_PULSE_WIDTH_MS;
|
||||
}
|
||||
|
||||
ds1809_pulse_direction(increment, decrement, count, pulse_ms, pulse_ms);
|
||||
}
|
||||
|
||||
void ds1809_apply_position_from_min(uint8_t position_from_min)
|
||||
{
|
||||
/*
|
||||
* DS1809 CPU-driven timing requirements from the local datasheet:
|
||||
* - a pulse must stay low for longer than 1 ms to count as a step;
|
||||
* - repetitive pulses need at least 1 ms of high time between steps;
|
||||
* - the control inputs are locked out for at least 10 ms after power-up.
|
||||
*
|
||||
* Use 8 ms low/high timing for margin, always drive to the RL end first,
|
||||
* then walk back up to the requested absolute position.
|
||||
*/
|
||||
if (position_from_min >= DS1809_POSITION_COUNT)
|
||||
{
|
||||
position_from_min = (uint8_t)(DS1809_POSITION_COUNT - 1u);
|
||||
}
|
||||
|
||||
HAL_Delay(DS1809_CONTROL_PORT_READY_DELAY_MS);
|
||||
ds1809_pulse_direction(0u, 1u, DS1809_RESET_DOWN_PULSE_COUNT, DS1809_CPU_PULSE_WIDTH_MS, DS1809_CPU_INTER_PULSE_HIGH_MS);
|
||||
ds1809_pulse_direction(1u, 0u, position_from_min, DS1809_CPU_PULSE_WIDTH_MS, DS1809_CPU_INTER_PULSE_HIGH_MS);
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
/**
|
||||
* @file ds1809_device.h
|
||||
* @brief DS1809 pulse-based control helper.
|
||||
*/
|
||||
|
||||
#ifndef DS1809_DEVICE_H
|
||||
#define DS1809_DEVICE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Send relative UC/DC pulses using the legacy serial-command semantics.
|
||||
*
|
||||
* @param increment Non-zero to pulse the UC pin.
|
||||
* @param decrement Non-zero to pulse the DC pin.
|
||||
* @param count Number of pulses to issue.
|
||||
* @param pulse_ms Low time and inter-pulse high time, in milliseconds.
|
||||
*/
|
||||
void ds1809_pulse(uint8_t increment, uint8_t decrement, uint16_t count, uint16_t pulse_ms);
|
||||
|
||||
/**
|
||||
* @brief Force the DS1809 to a known absolute position above the minimum tap.
|
||||
*
|
||||
* The helper first overdrives the wiper all the way down to the RL terminal and
|
||||
* then steps back up to the requested tap. This makes the standalone profile
|
||||
* path deterministic even though the DS1809 serial command itself is relative.
|
||||
*
|
||||
* @param position_from_min Number of upward steps above the minimum tap.
|
||||
*/
|
||||
void ds1809_apply_position_from_min(uint8_t position_from_min);
|
||||
|
||||
#endif /* DS1809_DEVICE_H */
|
||||
@ -1,103 +0,0 @@
|
||||
/**
|
||||
* @file laser_dac.c
|
||||
* @brief External DAC access for laser-current and TEC channels.
|
||||
*/
|
||||
|
||||
#include "laser_dac.h"
|
||||
|
||||
#include "board_io.h"
|
||||
#include "main.h"
|
||||
|
||||
void laser_dac_write_channel(uint8_t channel, uint16_t value)
|
||||
{
|
||||
uint32_t timeout;
|
||||
|
||||
if ((channel == 1u) || (channel == 3u))
|
||||
{
|
||||
board_io_configure_spi2_mode(LL_SPI_POLARITY_HIGH, LL_SPI_PHASE_2EDGE);
|
||||
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
switch (channel)
|
||||
{
|
||||
case 1u:
|
||||
HAL_GPIO_WritePin(DAC_LD1_CS_GPIO_Port, DAC_LD1_CS_Pin, GPIO_PIN_RESET);
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_TXE(SPI2)) && (timeout <= 500u))
|
||||
{
|
||||
++timeout;
|
||||
}
|
||||
LL_SPI_TransmitData16(SPI2, value);
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI2)) && (timeout <= 500u))
|
||||
{
|
||||
++timeout;
|
||||
}
|
||||
(void)SPI2->DR;
|
||||
break;
|
||||
|
||||
case 2u:
|
||||
if (!LL_SPI_IsEnabled(SPI6))
|
||||
{
|
||||
LL_SPI_Enable(SPI6);
|
||||
}
|
||||
HAL_GPIO_WritePin(DAC_LD2_CS_GPIO_Port, DAC_LD2_CS_Pin, GPIO_PIN_RESET);
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_TXE(SPI6)) && (timeout <= 500u))
|
||||
{
|
||||
++timeout;
|
||||
}
|
||||
LL_SPI_TransmitData16(SPI6, value);
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI6)) && (timeout <= 500u))
|
||||
{
|
||||
++timeout;
|
||||
}
|
||||
(void)SPI6->DR;
|
||||
break;
|
||||
|
||||
case 3u:
|
||||
HAL_GPIO_WritePin(DAC_TEC1_CS_GPIO_Port, DAC_TEC1_CS_Pin, GPIO_PIN_RESET);
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_TXE(SPI2)) && (timeout <= 500u))
|
||||
{
|
||||
++timeout;
|
||||
}
|
||||
LL_SPI_TransmitData16(SPI2, value);
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI2)) && (timeout <= 500u))
|
||||
{
|
||||
++timeout;
|
||||
}
|
||||
(void)SPI2->DR;
|
||||
break;
|
||||
|
||||
case 4u:
|
||||
if (!LL_SPI_IsEnabled(SPI6))
|
||||
{
|
||||
LL_SPI_Enable(SPI6);
|
||||
}
|
||||
HAL_GPIO_WritePin(DAC_TEC2_CS_GPIO_Port, DAC_TEC2_CS_Pin, GPIO_PIN_RESET);
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_TXE(SPI6)) && (timeout <= 500u))
|
||||
{
|
||||
++timeout;
|
||||
}
|
||||
LL_SPI_TransmitData16(SPI6, value);
|
||||
timeout = 0u;
|
||||
while ((!LL_SPI_IsActiveFlag_RXNE(SPI6)) && (timeout <= 500u))
|
||||
{
|
||||
++timeout;
|
||||
}
|
||||
(void)SPI6->DR;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
HAL_GPIO_WritePin(DAC_LD1_CS_GPIO_Port, DAC_LD1_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(DAC_LD2_CS_GPIO_Port, DAC_LD2_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(DAC_TEC1_CS_GPIO_Port, DAC_TEC1_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(DAC_TEC2_CS_GPIO_Port, DAC_TEC2_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
/**
|
||||
* @file laser_dac.h
|
||||
* @brief Drivers for the external laser-current and TEC DAC channels.
|
||||
*/
|
||||
|
||||
#ifndef LASER_DAC_H
|
||||
#define LASER_DAC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void laser_dac_write_channel(uint8_t channel, uint16_t value);
|
||||
|
||||
#endif /* LASER_DAC_H */
|
||||
@ -1,199 +0,0 @@
|
||||
/**
|
||||
* @file lcd1602_display.c
|
||||
* @brief Minimal SPLC780D/HD44780-compatible LCD1602 driver in 4-bit mode.
|
||||
*
|
||||
* Architectural note:
|
||||
* The chosen wiring keeps the whole standalone UI on GPIOG. This driver uses
|
||||
* write-only transfers with fixed delays, which keeps the implementation
|
||||
* compact and avoids a bidirectional R/W pin or extra state.
|
||||
*/
|
||||
|
||||
#include "lcd1602_display.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define LCD1602_COLUMNS 16u
|
||||
#define LCD1602_LINE_1_ADDRESS 0x00u
|
||||
#define LCD1602_LINE_2_ADDRESS 0x40u
|
||||
#define LCD1602_COMMAND_DELAY_US 50u
|
||||
#define LCD1602_CLEAR_DELAY_US 2000u
|
||||
#define LCD1602_ENABLE_PULSE_US 1u
|
||||
#define LCD1602_POWER_ON_DELAY_US 50000u
|
||||
|
||||
#define LCD1602_DATA_MASK (UI_LCD_D4_Pin | UI_LCD_D5_Pin | UI_LCD_D6_Pin | UI_LCD_D7_Pin)
|
||||
|
||||
static uint8_t g_cycle_counter_available = 0u;
|
||||
|
||||
static void lcd1602_enable_cycle_counter(void);
|
||||
static void lcd1602_delay_us(uint32_t delay_us);
|
||||
static void lcd1602_write_nibble(uint8_t nibble);
|
||||
static void lcd1602_pulse_enable(void);
|
||||
static void lcd1602_write_byte(bool is_data, uint8_t value);
|
||||
static void lcd1602_write_command(uint8_t command);
|
||||
static void lcd1602_write_data(uint8_t value);
|
||||
static void lcd1602_set_cursor(uint8_t address);
|
||||
static void lcd1602_write_padded_line(const char *text);
|
||||
|
||||
void lcd1602_display_init(void)
|
||||
{
|
||||
lcd1602_enable_cycle_counter();
|
||||
|
||||
HAL_GPIO_WritePin(UI_LCD_RS_GPIO_Port, UI_LCD_RS_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(UI_LCD_E_GPIO_Port, UI_LCD_E_Pin, GPIO_PIN_RESET);
|
||||
UI_LCD_D4_GPIO_Port->BSRR = ((uint32_t)LCD1602_DATA_MASK) << 16u;
|
||||
|
||||
lcd1602_delay_us(LCD1602_POWER_ON_DELAY_US);
|
||||
|
||||
lcd1602_write_nibble(0x03u);
|
||||
lcd1602_delay_us(5000u);
|
||||
lcd1602_write_nibble(0x03u);
|
||||
lcd1602_delay_us(150u);
|
||||
lcd1602_write_nibble(0x03u);
|
||||
lcd1602_delay_us(150u);
|
||||
lcd1602_write_nibble(0x02u);
|
||||
lcd1602_delay_us(LCD1602_COMMAND_DELAY_US);
|
||||
|
||||
lcd1602_write_command(0x28u);
|
||||
lcd1602_write_command(0x08u);
|
||||
lcd1602_write_command(0x01u);
|
||||
lcd1602_write_command(0x06u);
|
||||
lcd1602_write_command(0x0Cu);
|
||||
}
|
||||
|
||||
void lcd1602_display_set_lines(const char *line1, const char *line2)
|
||||
{
|
||||
lcd1602_set_cursor(LCD1602_LINE_1_ADDRESS);
|
||||
lcd1602_write_padded_line(line1);
|
||||
lcd1602_set_cursor(LCD1602_LINE_2_ADDRESS);
|
||||
lcd1602_write_padded_line(line2);
|
||||
}
|
||||
|
||||
static void lcd1602_enable_cycle_counter(void)
|
||||
{
|
||||
uint32_t start_cycles;
|
||||
uint32_t spin;
|
||||
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
DWT->CYCCNT = 0u;
|
||||
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
|
||||
|
||||
start_cycles = DWT->CYCCNT;
|
||||
for (spin = 0u; spin < 64u; ++spin)
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
|
||||
/*
|
||||
* DWT-based microsecond delays are convenient, but they are not
|
||||
* guaranteed to be available in every production boot/debug state.
|
||||
* Falling back to HAL_Delay() keeps the LCD optional rather than
|
||||
* letting the standalone UI block the whole firmware startup.
|
||||
*/
|
||||
g_cycle_counter_available = (DWT->CYCCNT != start_cycles) ? 1u : 0u;
|
||||
}
|
||||
|
||||
static void lcd1602_delay_us(uint32_t delay_us)
|
||||
{
|
||||
if (delay_us == 0u)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_cycle_counter_available != 0u)
|
||||
{
|
||||
uint32_t start_cycles = DWT->CYCCNT;
|
||||
uint32_t target_cycles = delay_us * (SystemCoreClock / 1000000u);
|
||||
|
||||
while ((DWT->CYCCNT - start_cycles) < target_cycles)
|
||||
{
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while (delay_us > 1000u)
|
||||
{
|
||||
HAL_Delay(1u);
|
||||
delay_us -= 1000u;
|
||||
}
|
||||
|
||||
HAL_Delay(1u);
|
||||
}
|
||||
|
||||
static void lcd1602_write_nibble(uint8_t nibble)
|
||||
{
|
||||
uint32_t bsrr = ((uint32_t)LCD1602_DATA_MASK) << 16u;
|
||||
|
||||
if ((nibble & 0x01u) != 0u)
|
||||
{
|
||||
bsrr |= UI_LCD_D4_Pin;
|
||||
}
|
||||
if ((nibble & 0x02u) != 0u)
|
||||
{
|
||||
bsrr |= UI_LCD_D5_Pin;
|
||||
}
|
||||
if ((nibble & 0x04u) != 0u)
|
||||
{
|
||||
bsrr |= UI_LCD_D6_Pin;
|
||||
}
|
||||
if ((nibble & 0x08u) != 0u)
|
||||
{
|
||||
bsrr |= UI_LCD_D7_Pin;
|
||||
}
|
||||
|
||||
UI_LCD_D4_GPIO_Port->BSRR = bsrr;
|
||||
lcd1602_pulse_enable();
|
||||
}
|
||||
|
||||
static void lcd1602_pulse_enable(void)
|
||||
{
|
||||
HAL_GPIO_WritePin(UI_LCD_E_GPIO_Port, UI_LCD_E_Pin, GPIO_PIN_SET);
|
||||
lcd1602_delay_us(LCD1602_ENABLE_PULSE_US);
|
||||
HAL_GPIO_WritePin(UI_LCD_E_GPIO_Port, UI_LCD_E_Pin, GPIO_PIN_RESET);
|
||||
lcd1602_delay_us(LCD1602_COMMAND_DELAY_US);
|
||||
}
|
||||
|
||||
static void lcd1602_write_byte(bool is_data, uint8_t value)
|
||||
{
|
||||
HAL_GPIO_WritePin(UI_LCD_RS_GPIO_Port, UI_LCD_RS_Pin, is_data ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||
lcd1602_write_nibble((uint8_t)(value >> 4u));
|
||||
lcd1602_write_nibble((uint8_t)(value & 0x0Fu));
|
||||
}
|
||||
|
||||
static void lcd1602_write_command(uint8_t command)
|
||||
{
|
||||
lcd1602_write_byte(false, command);
|
||||
|
||||
if ((command == 0x01u) || (command == 0x02u))
|
||||
{
|
||||
lcd1602_delay_us(LCD1602_CLEAR_DELAY_US);
|
||||
}
|
||||
}
|
||||
|
||||
static void lcd1602_write_data(uint8_t value)
|
||||
{
|
||||
lcd1602_write_byte(true, value);
|
||||
}
|
||||
|
||||
static void lcd1602_set_cursor(uint8_t address)
|
||||
{
|
||||
lcd1602_write_command((uint8_t)(0x80u | address));
|
||||
}
|
||||
|
||||
static void lcd1602_write_padded_line(const char *text)
|
||||
{
|
||||
uint8_t index;
|
||||
uint8_t value;
|
||||
|
||||
for (index = 0u; index < LCD1602_COLUMNS; ++index)
|
||||
{
|
||||
value = ' ';
|
||||
if ((text != NULL) && (text[index] != '\0'))
|
||||
{
|
||||
value = (uint8_t)text[index];
|
||||
}
|
||||
lcd1602_write_data(value);
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
/**
|
||||
* @file lcd1602_display.h
|
||||
* @brief Minimal SPLC780D/HD44780-compatible LCD1602 driver in 4-bit mode.
|
||||
*
|
||||
* Architectural note:
|
||||
* This module owns the LCD bus timing and character writes for the standalone
|
||||
* front panel. High-level services format text elsewhere and call this driver
|
||||
* only with already-prepared 16-character lines.
|
||||
*/
|
||||
|
||||
#ifndef LCD1602_DISPLAY_H
|
||||
#define LCD1602_DISPLAY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void lcd1602_display_init(void);
|
||||
void lcd1602_display_set_lines(const char *line1, const char *line2);
|
||||
|
||||
#endif /* LCD1602_DISPLAY_H */
|
||||
@ -1,45 +0,0 @@
|
||||
/**
|
||||
* @file stm32_dac_output.c
|
||||
* @brief STM32 internal DAC helper for the PA4 analogue output.
|
||||
*/
|
||||
|
||||
#include "stm32_dac_output.h"
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define STM32_DAC_MAX_CODE 4095u
|
||||
|
||||
void stm32_dac_output_init(void)
|
||||
{
|
||||
GPIO_InitTypeDef gpio_init = {0};
|
||||
|
||||
__HAL_RCC_DAC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
|
||||
gpio_init.Pin = GPIO_PIN_4;
|
||||
gpio_init.Mode = GPIO_MODE_ANALOG;
|
||||
gpio_init.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOA, &gpio_init);
|
||||
|
||||
DAC->CR &= ~(DAC_CR_EN1 | DAC_CR_TEN1 | DAC_CR_DMAEN1);
|
||||
DAC->DHR12R1 = 0u;
|
||||
}
|
||||
|
||||
void stm32_dac_output_set(uint16_t dac_code, uint8_t enabled)
|
||||
{
|
||||
if (dac_code > STM32_DAC_MAX_CODE)
|
||||
{
|
||||
dac_code = STM32_DAC_MAX_CODE;
|
||||
}
|
||||
|
||||
DAC->DHR12R1 = dac_code;
|
||||
|
||||
if (enabled != 0u)
|
||||
{
|
||||
DAC->CR |= DAC_CR_EN1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DAC->CR &= ~DAC_CR_EN1;
|
||||
}
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
/**
|
||||
* @file stm32_dac_output.h
|
||||
* @brief STM32 internal DAC helper for PA4 output generation.
|
||||
*/
|
||||
|
||||
#ifndef STM32_DAC_OUTPUT_H
|
||||
#define STM32_DAC_OUTPUT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void stm32_dac_output_init(void);
|
||||
void stm32_dac_output_set(uint16_t dac_code, uint8_t enabled);
|
||||
|
||||
#endif /* STM32_DAC_OUTPUT_H */
|
||||
@ -1,68 +0,0 @@
|
||||
/**
|
||||
* @file uart_transport.c
|
||||
* @brief USART1 transmit helpers used by the application core.
|
||||
*/
|
||||
|
||||
#include "uart_transport.h"
|
||||
|
||||
#include "main.h"
|
||||
|
||||
static volatile uint8_t g_dma_busy = 0u;
|
||||
|
||||
void uart_transport_init(void)
|
||||
{
|
||||
LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_7);
|
||||
LL_DMA_ClearFlag_TC7(DMA2);
|
||||
LL_DMA_ClearFlag_TE7(DMA2);
|
||||
LL_USART_EnableDMAReq_TX(USART1);
|
||||
LL_DMA_EnableIT_TC(DMA2, LL_DMA_STREAM_7);
|
||||
LL_DMA_EnableIT_TE(DMA2, LL_DMA_STREAM_7);
|
||||
g_dma_busy = 0u;
|
||||
}
|
||||
|
||||
void uart_transport_reset(void)
|
||||
{
|
||||
g_dma_busy = 0u;
|
||||
}
|
||||
|
||||
void uart_transport_send_blocking(const uint8_t *data, uint16_t size)
|
||||
{
|
||||
uint16_t index;
|
||||
|
||||
for (index = 0u; index < size; ++index)
|
||||
{
|
||||
while (!LL_USART_IsActiveFlag_TXE(USART1))
|
||||
{
|
||||
}
|
||||
LL_USART_TransmitData8(USART1, data[index]);
|
||||
}
|
||||
}
|
||||
|
||||
void uart_transport_send_dma(const uint8_t *data, uint16_t size)
|
||||
{
|
||||
while (g_dma_busy != 0u)
|
||||
{
|
||||
}
|
||||
|
||||
LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_7);
|
||||
LL_DMA_ClearFlag_TC7(DMA2);
|
||||
LL_DMA_ClearFlag_TE7(DMA2);
|
||||
LL_DMA_ConfigAddresses(DMA2,
|
||||
LL_DMA_STREAM_7,
|
||||
(uint32_t)data,
|
||||
LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_TRANSMIT),
|
||||
LL_DMA_GetDataTransferDirection(DMA2, LL_DMA_STREAM_7));
|
||||
LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_7, size);
|
||||
g_dma_busy = 1u;
|
||||
LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_7);
|
||||
}
|
||||
|
||||
void uart_transport_mark_dma_complete(void)
|
||||
{
|
||||
g_dma_busy = 0u;
|
||||
}
|
||||
|
||||
bool uart_transport_is_dma_busy(void)
|
||||
{
|
||||
return g_dma_busy != 0u;
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
/**
|
||||
* @file uart_transport.h
|
||||
* @brief USART1 transmit helpers used by the application core.
|
||||
*/
|
||||
|
||||
#ifndef UART_TRANSPORT_H
|
||||
#define UART_TRANSPORT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void uart_transport_init(void);
|
||||
void uart_transport_reset(void);
|
||||
void uart_transport_send_blocking(const uint8_t *data, uint16_t size);
|
||||
void uart_transport_send_dma(const uint8_t *data, uint16_t size);
|
||||
void uart_transport_mark_dma_complete(void);
|
||||
bool uart_transport_is_dma_busy(void);
|
||||
|
||||
#endif /* UART_TRANSPORT_H */
|
||||
@ -1,374 +0,0 @@
|
||||
/**
|
||||
* @file app_types.h
|
||||
* @brief Shared application-level types, constants, and protocol identifiers.
|
||||
*
|
||||
* Architectural note:
|
||||
* This header owns the firmware vocabulary used by the modular App layer.
|
||||
* CubeMX-generated headers keep only board-level definitions, while every
|
||||
* application module includes these types to communicate through explicit
|
||||
* interfaces instead of ad-hoc globals and scattered macros.
|
||||
*/
|
||||
|
||||
#ifndef APP_TYPES_H
|
||||
#define APP_TYPES_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** @brief Total number of 16-bit words in a telemetry frame, including header. */
|
||||
#define APP_TELEMETRY_WORD_COUNT 15u
|
||||
|
||||
/** @brief Total number of bytes in a telemetry frame. */
|
||||
#define APP_TELEMETRY_FRAME_BYTES 30u
|
||||
|
||||
/** @brief Maximum number of payload words stored by the UART protocol parser. */
|
||||
#define APP_PROTOCOL_MAX_PAYLOAD_WORDS 15u
|
||||
|
||||
/** @brief Maximum packet size handled by the UART protocol parser. */
|
||||
#define APP_PROTOCOL_MAX_PACKET_BYTES 32u
|
||||
|
||||
/** @brief Maximum number of visible characters allowed in a saved profile name. */
|
||||
#define APP_PROFILE_NAME_MAX_CHARACTERS 16u
|
||||
|
||||
/** @brief Maximum profile display-name length, including the terminating NUL. */
|
||||
#define APP_PROFILE_NAME_LENGTH (APP_PROFILE_NAME_MAX_CHARACTERS + 1u)
|
||||
|
||||
/** @brief Maximum stored path length for profile and waveform files. */
|
||||
#define APP_PROFILE_PATH_LENGTH 96u
|
||||
|
||||
/** @brief Future profile list file for SD-card based standalone operation. */
|
||||
#define APP_STORAGE_PROFILE_INDEX_FILE "profiles.csv"
|
||||
|
||||
/** @brief UART header for the host work-configuration packet. */
|
||||
#define APP_PACKET_HEADER_WORK_CONFIG 0x1111u
|
||||
|
||||
/** @brief UART header for the "return to defaults" command. */
|
||||
#define APP_PACKET_HEADER_DEFAULTS 0x2222u
|
||||
|
||||
/** @brief UART header for the "transmit live telemetry" command. */
|
||||
#define APP_PACKET_HEADER_TX_CURRENT 0x4444u
|
||||
|
||||
/** @brief UART header for the "query state" command. */
|
||||
#define APP_PACKET_HEADER_QUERY_STATE 0x6666u
|
||||
|
||||
/** @brief UART header for profile-save control packets. */
|
||||
#define APP_PACKET_HEADER_PROFILE_SAVE_CONTROL 0x7777u
|
||||
|
||||
/** @brief UART header for the AD9102 control packet. */
|
||||
#define APP_PACKET_HEADER_AD9102_CONTROL 0x8888u
|
||||
|
||||
/** @brief UART header for the AD9833 control packet. */
|
||||
#define APP_PACKET_HEADER_AD9833_CONTROL 0x9999u
|
||||
|
||||
/** @brief UART header for the DS1809 control packet. */
|
||||
#define APP_PACKET_HEADER_DS1809_CONTROL 0xAAAAu
|
||||
|
||||
/** @brief UART header for the STM32 internal DAC control packet. */
|
||||
#define APP_PACKET_HEADER_STM32_DAC_CONTROL 0xBBBBu
|
||||
|
||||
/** @brief UART header for the AD9102 waveform upload control packet. */
|
||||
#define APP_PACKET_HEADER_AD9102_WAVE_CONTROL 0xCCCCu
|
||||
|
||||
/** @brief UART header for the AD9102 waveform upload data packet. */
|
||||
#define APP_PACKET_HEADER_AD9102_WAVE_DATA 0xDDDDu
|
||||
|
||||
/** @brief UART header for profile-save data packets. */
|
||||
#define APP_PACKET_HEADER_PROFILE_SAVE_DATA 0xEEEEu
|
||||
|
||||
/** @brief UART header for TEC drive modulation control packets. */
|
||||
#define APP_PACKET_HEADER_TEC_MODULATION_CONTROL 0xF0F0u
|
||||
|
||||
/** @brief Packet size of the host work-configuration message, in bytes. */
|
||||
#define APP_PACKET_BYTES_WORK_CONFIG 30u
|
||||
|
||||
/** @brief Packet size of short control messages, in bytes. */
|
||||
#define APP_PACKET_BYTES_SHORT_CONTROL 10u
|
||||
|
||||
/** @brief Packet size of AD9102 waveform-data messages, in bytes. */
|
||||
#define APP_PACKET_BYTES_AD9102_WAVE_DATA 30u
|
||||
|
||||
/** @brief Packet size of profile-save control messages, in bytes. */
|
||||
#define APP_PACKET_BYTES_PROFILE_SAVE_CONTROL 30u
|
||||
|
||||
/** @brief Packet size of profile-save data messages, in bytes. */
|
||||
#define APP_PACKET_BYTES_PROFILE_SAVE_DATA 30u
|
||||
|
||||
/** @brief Number of payload words carried by the host work packet. */
|
||||
#define APP_PACKET_WORDS_WORK_CONFIG 14u
|
||||
|
||||
/** @brief Number of payload words carried by short control packets. */
|
||||
#define APP_PACKET_WORDS_SHORT_CONTROL 4u
|
||||
|
||||
/** @brief Number of payload words carried by AD9102 waveform-data packets. */
|
||||
#define APP_PACKET_WORDS_AD9102_WAVE_DATA 14u
|
||||
|
||||
/** @brief Number of payload words carried by profile-save control packets. */
|
||||
#define APP_PACKET_WORDS_PROFILE_SAVE_CONTROL 14u
|
||||
|
||||
/** @brief Number of payload words carried by profile-save data packets. */
|
||||
#define APP_PACKET_WORDS_PROFILE_SAVE_DATA 14u
|
||||
|
||||
/** @brief First status byte flag for SD-card related errors. */
|
||||
#define APP_STATUS_FLAG_SD_ERROR 0x01u
|
||||
|
||||
/** @brief First status byte flag for UART framing/header errors. */
|
||||
#define APP_STATUS_FLAG_UART_ERROR 0x02u
|
||||
|
||||
/** @brief First status byte flag for checksum or payload validation errors. */
|
||||
#define APP_STATUS_FLAG_UART_DECODE_ERROR 0x04u
|
||||
|
||||
/** @brief First status byte flag for TEC1-related runtime errors. */
|
||||
#define APP_STATUS_FLAG_TEC1_ERROR 0x08u
|
||||
|
||||
/** @brief First status byte flag for TEC2-related runtime errors. */
|
||||
#define APP_STATUS_FLAG_TEC2_ERROR 0x10u
|
||||
|
||||
/** @brief First status byte flag for default/reset handling errors. */
|
||||
#define APP_STATUS_FLAG_DEFAULT_ERROR 0x20u
|
||||
|
||||
/** @brief First status byte flag for AD9102 configuration/upload errors. */
|
||||
#define APP_STATUS_FLAG_AD9102_ERROR 0x80u
|
||||
|
||||
/** @brief AD9102 control flag: enable or disable output. */
|
||||
#define APP_AD9102_FLAG_ENABLE 0x0001u
|
||||
|
||||
/** @brief AD9102 control flag: select triangle instead of saw ramp. */
|
||||
#define APP_AD9102_FLAG_TRIANGLE 0x0002u
|
||||
|
||||
/** @brief AD9102 control flag: use SRAM-backed waveform path. */
|
||||
#define APP_AD9102_FLAG_SRAM 0x0004u
|
||||
|
||||
/** @brief AD9102 control flag: use amplitude/sample-count short format. */
|
||||
#define APP_AD9102_FLAG_SRAM_FORMAT_ALT 0x0008u
|
||||
|
||||
/** @brief AD9833 control flag: enable or disable output. */
|
||||
#define APP_AD9833_FLAG_ENABLE 0x0001u
|
||||
|
||||
/** @brief AD9833 control flag: select triangle mode. */
|
||||
#define APP_AD9833_FLAG_TRIANGLE 0x0002u
|
||||
|
||||
/** @brief DS1809 control flag: pulse the "up" control line. */
|
||||
#define APP_DS1809_FLAG_INCREMENT 0x0001u
|
||||
|
||||
/** @brief DS1809 control flag: pulse the "down" control line. */
|
||||
#define APP_DS1809_FLAG_DECREMENT 0x0002u
|
||||
|
||||
/** @brief STM32 DAC control flag: enable output buffer/channel. */
|
||||
#define APP_STM32_DAC_FLAG_ENABLE 0x0001u
|
||||
|
||||
/** @brief TEC modulation control flag: enable modulation. */
|
||||
#define APP_TEC_MODULATION_FLAG_ENABLE 0x0001u
|
||||
|
||||
/** @brief TEC modulation control flag: select laser/TEC channel 2 instead of channel 1. */
|
||||
#define APP_TEC_MODULATION_FLAG_CHANNEL_2 0x0002u
|
||||
|
||||
/** @brief Lowest accepted TEC modulation frequency in hertz. */
|
||||
#define APP_TEC_MODULATION_MIN_FREQUENCY_HZ 50u
|
||||
|
||||
/** @brief Highest accepted TEC modulation frequency in hertz. */
|
||||
#define APP_TEC_MODULATION_MAX_FREQUENCY_HZ 2000u
|
||||
|
||||
/** @brief Highest accepted peak modulation amplitude in external TEC DAC codes. */
|
||||
#define APP_TEC_MODULATION_MAX_AMPLITUDE_CODE 4096u
|
||||
|
||||
/** @brief Op-code used to begin a custom AD9102 waveform upload. */
|
||||
#define APP_AD9102_WAVE_OPCODE_BEGIN 0x0001u
|
||||
|
||||
/** @brief Op-code used to commit a custom AD9102 waveform upload. */
|
||||
#define APP_AD9102_WAVE_OPCODE_COMMIT 0x0002u
|
||||
|
||||
/** @brief Op-code used to cancel a custom AD9102 waveform upload. */
|
||||
#define APP_AD9102_WAVE_OPCODE_CANCEL 0x0003u
|
||||
|
||||
/** @brief Op-code used to begin a streamed profile-save session. */
|
||||
#define APP_PROFILE_SAVE_OPCODE_BEGIN 0x0001u
|
||||
|
||||
/** @brief Op-code used to commit a streamed profile-save session. */
|
||||
#define APP_PROFILE_SAVE_OPCODE_COMMIT 0x0002u
|
||||
|
||||
/** @brief Op-code used to cancel a streamed profile-save session. */
|
||||
#define APP_PROFILE_SAVE_OPCODE_CANCEL 0x0003u
|
||||
|
||||
/** @brief Section id used for profile INI text chunks during profile save. */
|
||||
#define APP_PROFILE_SAVE_SECTION_PROFILE_TEXT 0x0001u
|
||||
|
||||
/** @brief Section id used for optional waveform CSV chunks during profile save. */
|
||||
#define APP_PROFILE_SAVE_SECTION_WAVEFORM_TEXT 0x0002u
|
||||
|
||||
/** @brief Maximum number of raw data bytes carried by one profile-save data packet. */
|
||||
#define APP_PROFILE_SAVE_MAX_DATA_BYTES_PER_PACKET 22u
|
||||
|
||||
/**
|
||||
* @brief High-level runtime modes executed by the application core.
|
||||
*/
|
||||
typedef enum app_mode_t {
|
||||
APP_MODE_IDLE = 0,
|
||||
APP_MODE_WORK,
|
||||
APP_MODE_TX_CURRENT,
|
||||
APP_MODE_ERROR
|
||||
} app_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Deferred application events injected by future UI/GPIO frontends.
|
||||
*/
|
||||
typedef enum app_event_t {
|
||||
APP_EVENT_NONE = 0,
|
||||
APP_EVENT_PROFILE_NEXT
|
||||
} app_event_t;
|
||||
|
||||
/**
|
||||
* @brief Internal transmission slots queued by the application core.
|
||||
*/
|
||||
typedef enum app_tx_request_t {
|
||||
APP_TX_REQUEST_NONE = 0,
|
||||
APP_TX_REQUEST_STATUS,
|
||||
APP_TX_REQUEST_CURRENT_FRAME
|
||||
} app_tx_request_t;
|
||||
|
||||
/**
|
||||
* @brief Packet kinds emitted by the UART protocol parser.
|
||||
*/
|
||||
typedef enum app_packet_kind_t {
|
||||
APP_PACKET_KIND_NONE = 0,
|
||||
APP_PACKET_KIND_WORK_CONFIG,
|
||||
APP_PACKET_KIND_DEFAULTS,
|
||||
APP_PACKET_KIND_TX_CURRENT,
|
||||
APP_PACKET_KIND_QUERY_STATE,
|
||||
APP_PACKET_KIND_PROFILE_SAVE_CONTROL,
|
||||
APP_PACKET_KIND_AD9102_CONTROL,
|
||||
APP_PACKET_KIND_AD9833_CONTROL,
|
||||
APP_PACKET_KIND_DS1809_CONTROL,
|
||||
APP_PACKET_KIND_STM32_DAC_CONTROL,
|
||||
APP_PACKET_KIND_AD9102_WAVE_CONTROL,
|
||||
APP_PACKET_KIND_AD9102_WAVE_DATA,
|
||||
APP_PACKET_KIND_PROFILE_SAVE_DATA,
|
||||
APP_PACKET_KIND_TEC_MODULATION_CONTROL
|
||||
} app_packet_kind_t;
|
||||
|
||||
/**
|
||||
* @brief User-visible signal-generation mode for the AD9102 path.
|
||||
*/
|
||||
typedef enum waveform_mode_t {
|
||||
WAVEFORM_MODE_SAW = 0,
|
||||
WAVEFORM_MODE_SRAM_GENERATED,
|
||||
WAVEFORM_MODE_SRAM_CUSTOM
|
||||
} waveform_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Packed enable flags and misc runtime settings for the board.
|
||||
*/
|
||||
typedef struct work_config_t {
|
||||
uint8_t work_enabled;
|
||||
uint8_t supply_5v1_enabled;
|
||||
uint8_t supply_5v2_enabled;
|
||||
uint8_t laser1_enabled;
|
||||
uint8_t laser2_enabled;
|
||||
uint8_t reference1_enabled;
|
||||
uint8_t reference2_enabled;
|
||||
uint8_t tec1_enabled;
|
||||
uint8_t tec2_enabled;
|
||||
uint8_t temp_sensor1_enabled;
|
||||
uint8_t temp_sensor2_enabled;
|
||||
uint8_t pid1_from_host;
|
||||
uint8_t pid2_from_host;
|
||||
uint16_t averages;
|
||||
uint16_t message_id;
|
||||
} work_config_t;
|
||||
|
||||
/**
|
||||
* @brief Runtime configuration of one laser channel.
|
||||
*/
|
||||
typedef struct laser_channel_config_t {
|
||||
uint16_t target_temperature_raw;
|
||||
float pid_p;
|
||||
float pid_i;
|
||||
uint16_t current_raw;
|
||||
} laser_channel_config_t;
|
||||
|
||||
/**
|
||||
* @brief Mutable per-channel runtime state derived from sensor feedback.
|
||||
*/
|
||||
typedef struct laser_runtime_t {
|
||||
uint16_t current_temperature_raw;
|
||||
float integral_error;
|
||||
uint16_t power_raw;
|
||||
} laser_runtime_t;
|
||||
|
||||
/**
|
||||
* @brief Normalised configuration for AD9102 waveform control.
|
||||
*/
|
||||
typedef struct waveform_config_t {
|
||||
waveform_mode_t mode;
|
||||
uint8_t enabled;
|
||||
uint8_t triangle;
|
||||
uint8_t saw_step;
|
||||
uint8_t pat_period_base;
|
||||
uint16_t pat_period;
|
||||
uint16_t sample_count;
|
||||
uint8_t hold_cycles;
|
||||
uint16_t amplitude;
|
||||
char source_path[APP_PROFILE_PATH_LENGTH];
|
||||
} waveform_config_t;
|
||||
|
||||
/**
|
||||
* @brief AD9833 generator configuration mirrored from the serial-control path.
|
||||
*/
|
||||
typedef struct ad9833_config_t {
|
||||
uint8_t enabled;
|
||||
uint8_t triangle;
|
||||
uint32_t frequency_word;
|
||||
} ad9833_config_t;
|
||||
|
||||
/**
|
||||
* @brief STM32 internal DAC configuration mirrored from the serial-control path.
|
||||
*/
|
||||
typedef struct stm32_dac_config_t {
|
||||
uint8_t enabled;
|
||||
uint16_t code;
|
||||
} stm32_dac_config_t;
|
||||
|
||||
/**
|
||||
* @brief Fast zero-mean modulation added to one TEC DAC output after PID.
|
||||
*/
|
||||
typedef struct tec_modulation_config_t {
|
||||
uint8_t enabled;
|
||||
uint8_t channel_index;
|
||||
uint16_t frequency_hz;
|
||||
uint16_t amplitude_code;
|
||||
} tec_modulation_config_t;
|
||||
|
||||
/**
|
||||
* @brief Absolute DS1809 target expressed as a number of steps above the minimum tap.
|
||||
*/
|
||||
typedef struct ds1809_config_t {
|
||||
bool apply_position;
|
||||
uint8_t position_from_min;
|
||||
} ds1809_config_t;
|
||||
|
||||
/**
|
||||
* @brief Standalone profile model loaded from SD-card configuration.
|
||||
*/
|
||||
typedef struct profile_t {
|
||||
char display_name[APP_PROFILE_NAME_LENGTH];
|
||||
char profile_path[APP_PROFILE_PATH_LENGTH];
|
||||
char waveform_path[APP_PROFILE_PATH_LENGTH];
|
||||
bool auto_run;
|
||||
bool boot_enabled;
|
||||
work_config_t work_config;
|
||||
laser_channel_config_t laser_channels[2];
|
||||
waveform_config_t waveform;
|
||||
ad9833_config_t ad9833;
|
||||
stm32_dac_config_t stm32_dac;
|
||||
tec_modulation_config_t tec_modulation;
|
||||
ds1809_config_t ds1809;
|
||||
} profile_t;
|
||||
|
||||
/**
|
||||
* @brief Telemetry frame sent over UART.
|
||||
*/
|
||||
typedef struct telemetry_frame_t {
|
||||
uint16_t words[APP_TELEMETRY_WORD_COUNT];
|
||||
} telemetry_frame_t;
|
||||
|
||||
#endif /* APP_TYPES_H */
|
||||
@ -1,163 +0,0 @@
|
||||
/**
|
||||
* @file app_uart_protocol.c
|
||||
* @brief Table-driven incremental UART packet parser and checksum helpers.
|
||||
*/
|
||||
|
||||
#include "app_uart_protocol.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static const app_packet_descriptor_t g_packet_descriptors[] = {
|
||||
{APP_PACKET_HEADER_WORK_CONFIG, APP_PACKET_BYTES_WORK_CONFIG, APP_PACKET_WORDS_WORK_CONFIG, 13, APP_PACKET_KIND_WORK_CONFIG},
|
||||
{APP_PACKET_HEADER_DEFAULTS, 2u, 0u, -1, APP_PACKET_KIND_DEFAULTS},
|
||||
{APP_PACKET_HEADER_TX_CURRENT, 2u, 0u, -1, APP_PACKET_KIND_TX_CURRENT},
|
||||
{APP_PACKET_HEADER_QUERY_STATE, 2u, 0u, -1, APP_PACKET_KIND_QUERY_STATE},
|
||||
{APP_PACKET_HEADER_PROFILE_SAVE_CONTROL, APP_PACKET_BYTES_PROFILE_SAVE_CONTROL, APP_PACKET_WORDS_PROFILE_SAVE_CONTROL, 13, APP_PACKET_KIND_PROFILE_SAVE_CONTROL},
|
||||
{APP_PACKET_HEADER_AD9102_CONTROL, APP_PACKET_BYTES_SHORT_CONTROL, APP_PACKET_WORDS_SHORT_CONTROL, 3, APP_PACKET_KIND_AD9102_CONTROL},
|
||||
{APP_PACKET_HEADER_AD9833_CONTROL, APP_PACKET_BYTES_SHORT_CONTROL, APP_PACKET_WORDS_SHORT_CONTROL, 3, APP_PACKET_KIND_AD9833_CONTROL},
|
||||
{APP_PACKET_HEADER_DS1809_CONTROL, APP_PACKET_BYTES_SHORT_CONTROL, APP_PACKET_WORDS_SHORT_CONTROL, 3, APP_PACKET_KIND_DS1809_CONTROL},
|
||||
{APP_PACKET_HEADER_STM32_DAC_CONTROL, APP_PACKET_BYTES_SHORT_CONTROL, APP_PACKET_WORDS_SHORT_CONTROL, 3, APP_PACKET_KIND_STM32_DAC_CONTROL},
|
||||
{APP_PACKET_HEADER_AD9102_WAVE_CONTROL, APP_PACKET_BYTES_SHORT_CONTROL, APP_PACKET_WORDS_SHORT_CONTROL, 3, APP_PACKET_KIND_AD9102_WAVE_CONTROL},
|
||||
{APP_PACKET_HEADER_AD9102_WAVE_DATA, APP_PACKET_BYTES_AD9102_WAVE_DATA, APP_PACKET_WORDS_AD9102_WAVE_DATA, 13, APP_PACKET_KIND_AD9102_WAVE_DATA},
|
||||
{APP_PACKET_HEADER_PROFILE_SAVE_DATA, APP_PACKET_BYTES_PROFILE_SAVE_DATA, APP_PACKET_WORDS_PROFILE_SAVE_DATA, 13, APP_PACKET_KIND_PROFILE_SAVE_DATA},
|
||||
{APP_PACKET_HEADER_TEC_MODULATION_CONTROL, APP_PACKET_BYTES_SHORT_CONTROL, APP_PACKET_WORDS_SHORT_CONTROL, 3, APP_PACKET_KIND_TEC_MODULATION_CONTROL}
|
||||
};
|
||||
|
||||
static const app_packet_descriptor_t *app_uart_protocol_find_descriptor(uint16_t header)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
for (index = 0u; index < (sizeof(g_packet_descriptors) / sizeof(g_packet_descriptors[0])); ++index)
|
||||
{
|
||||
if (g_packet_descriptors[index].header == header)
|
||||
{
|
||||
return &g_packet_descriptors[index];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint16_t app_protocol_calculate_checksum(const uint16_t *words, uint16_t word_count)
|
||||
{
|
||||
uint16_t checksum;
|
||||
uint16_t index;
|
||||
|
||||
if ((words == NULL) || (word_count == 0u))
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
|
||||
checksum = words[0];
|
||||
for (index = 1u; index < word_count; ++index)
|
||||
{
|
||||
checksum ^= words[index];
|
||||
}
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
void app_uart_protocol_init(app_uart_protocol_parser_t *parser)
|
||||
{
|
||||
if (parser != NULL)
|
||||
{
|
||||
memset(parser, 0, sizeof(*parser));
|
||||
}
|
||||
}
|
||||
|
||||
void app_uart_protocol_reset(app_uart_protocol_parser_t *parser)
|
||||
{
|
||||
app_uart_protocol_init(parser);
|
||||
}
|
||||
|
||||
app_protocol_feed_result_t app_uart_protocol_feed_byte(app_uart_protocol_parser_t *parser,
|
||||
uint8_t byte,
|
||||
app_packet_t *out_packet)
|
||||
{
|
||||
uint8_t word_index;
|
||||
|
||||
if ((parser == NULL) || (out_packet == NULL))
|
||||
{
|
||||
return APP_PROTOCOL_FEED_IN_PROGRESS;
|
||||
}
|
||||
|
||||
if (parser->bytes_received == 0u)
|
||||
{
|
||||
parser->buffer[0] = byte;
|
||||
parser->partial_header = byte;
|
||||
parser->bytes_received = 1u;
|
||||
return APP_PROTOCOL_FEED_IN_PROGRESS;
|
||||
}
|
||||
|
||||
if (parser->bytes_received == 1u)
|
||||
{
|
||||
parser->buffer[1] = byte;
|
||||
parser->partial_header = (uint16_t)(parser->partial_header | ((uint16_t)byte << 8));
|
||||
parser->descriptor = app_uart_protocol_find_descriptor(parser->partial_header);
|
||||
|
||||
if (parser->descriptor == NULL)
|
||||
{
|
||||
app_uart_protocol_reset(parser);
|
||||
return APP_PROTOCOL_FEED_INVALID_HEADER;
|
||||
}
|
||||
|
||||
parser->bytes_received = 2u;
|
||||
if (parser->descriptor->total_bytes == 2u)
|
||||
{
|
||||
memset(out_packet, 0, sizeof(*out_packet));
|
||||
out_packet->kind = parser->descriptor->kind;
|
||||
out_packet->header = parser->descriptor->header;
|
||||
out_packet->checksum_valid = true;
|
||||
app_uart_protocol_reset(parser);
|
||||
return APP_PROTOCOL_FEED_PACKET_READY;
|
||||
}
|
||||
|
||||
return APP_PROTOCOL_FEED_IN_PROGRESS;
|
||||
}
|
||||
|
||||
if (parser->descriptor == NULL)
|
||||
{
|
||||
app_uart_protocol_reset(parser);
|
||||
return APP_PROTOCOL_FEED_INVALID_HEADER;
|
||||
}
|
||||
|
||||
if (parser->bytes_received >= parser->descriptor->total_bytes)
|
||||
{
|
||||
app_uart_protocol_reset(parser);
|
||||
return APP_PROTOCOL_FEED_INVALID_HEADER;
|
||||
}
|
||||
|
||||
parser->buffer[parser->bytes_received] = byte;
|
||||
++parser->bytes_received;
|
||||
|
||||
if (parser->bytes_received < parser->descriptor->total_bytes)
|
||||
{
|
||||
return APP_PROTOCOL_FEED_IN_PROGRESS;
|
||||
}
|
||||
|
||||
memset(out_packet, 0, sizeof(*out_packet));
|
||||
out_packet->kind = parser->descriptor->kind;
|
||||
out_packet->header = parser->descriptor->header;
|
||||
out_packet->payload_words = parser->descriptor->payload_words;
|
||||
|
||||
for (word_index = 0u; word_index < parser->descriptor->payload_words; ++word_index)
|
||||
{
|
||||
uint8_t byte_offset = (uint8_t)(2u + (word_index * 2u));
|
||||
out_packet->words[word_index] = (uint16_t)(parser->buffer[byte_offset] |
|
||||
((uint16_t)parser->buffer[byte_offset + 1u] << 8));
|
||||
}
|
||||
|
||||
if (parser->descriptor->checksum_word_index >= 0)
|
||||
{
|
||||
uint8_t checksum_index = (uint8_t)parser->descriptor->checksum_word_index;
|
||||
out_packet->checksum_valid =
|
||||
app_protocol_calculate_checksum(out_packet->words, checksum_index) == out_packet->words[checksum_index];
|
||||
}
|
||||
else
|
||||
{
|
||||
out_packet->checksum_valid = true;
|
||||
}
|
||||
|
||||
app_uart_protocol_reset(parser);
|
||||
return APP_PROTOCOL_FEED_PACKET_READY;
|
||||
}
|
||||
@ -1,68 +0,0 @@
|
||||
/**
|
||||
* @file app_uart_protocol.h
|
||||
* @brief Table-driven incremental UART packet parser and checksum helpers.
|
||||
*
|
||||
* Architectural note:
|
||||
* The parser is intentionally transport-agnostic. It receives one byte at a
|
||||
* time from the IRQ adapter, reconstructs packets according to a descriptor
|
||||
* table, validates checksums when applicable, and emits fully decoded packet
|
||||
* objects for the application core.
|
||||
*/
|
||||
|
||||
#ifndef APP_UART_PROTOCOL_H
|
||||
#define APP_UART_PROTOCOL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "app_types.h"
|
||||
|
||||
/**
|
||||
* @brief Descriptor describing one supported UART packet shape.
|
||||
*/
|
||||
typedef struct app_packet_descriptor_t {
|
||||
uint16_t header;
|
||||
uint8_t total_bytes;
|
||||
uint8_t payload_words;
|
||||
int8_t checksum_word_index;
|
||||
app_packet_kind_t kind;
|
||||
} app_packet_descriptor_t;
|
||||
|
||||
/**
|
||||
* @brief Parsed UART packet emitted by the protocol layer.
|
||||
*/
|
||||
typedef struct app_packet_t {
|
||||
app_packet_kind_t kind;
|
||||
uint16_t header;
|
||||
uint8_t payload_words;
|
||||
bool checksum_valid;
|
||||
uint16_t words[APP_PROTOCOL_MAX_PAYLOAD_WORDS];
|
||||
} app_packet_t;
|
||||
|
||||
/**
|
||||
* @brief Mutable state of the incremental UART parser.
|
||||
*/
|
||||
typedef struct app_uart_protocol_parser_t {
|
||||
const app_packet_descriptor_t *descriptor;
|
||||
uint16_t partial_header;
|
||||
uint8_t bytes_received;
|
||||
uint8_t buffer[APP_PROTOCOL_MAX_PACKET_BYTES];
|
||||
} app_uart_protocol_parser_t;
|
||||
|
||||
/**
|
||||
* @brief Result returned after feeding one byte into the parser.
|
||||
*/
|
||||
typedef enum app_protocol_feed_result_t {
|
||||
APP_PROTOCOL_FEED_IN_PROGRESS = 0,
|
||||
APP_PROTOCOL_FEED_PACKET_READY,
|
||||
APP_PROTOCOL_FEED_INVALID_HEADER
|
||||
} app_protocol_feed_result_t;
|
||||
|
||||
void app_uart_protocol_init(app_uart_protocol_parser_t *parser);
|
||||
void app_uart_protocol_reset(app_uart_protocol_parser_t *parser);
|
||||
app_protocol_feed_result_t app_uart_protocol_feed_byte(app_uart_protocol_parser_t *parser,
|
||||
uint8_t byte,
|
||||
app_packet_t *out_packet);
|
||||
uint16_t app_protocol_calculate_checksum(const uint16_t *words, uint16_t word_count);
|
||||
|
||||
#endif /* APP_UART_PROTOCOL_H */
|
||||
@ -1,557 +0,0 @@
|
||||
/**
|
||||
* @file profile_repository.c
|
||||
* @brief Future SD-card profile repository with minimal standalone parsing.
|
||||
*/
|
||||
|
||||
#include "profile_repository.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "ad9102_device.h"
|
||||
#include "storage_sd.h"
|
||||
|
||||
#define PROFILE_REPOSITORY_BUFFER_SIZE 1024u
|
||||
|
||||
static char *profile_repository_trim(char *text)
|
||||
{
|
||||
char *end;
|
||||
|
||||
while ((*text != '\0') && isspace((unsigned char)*text))
|
||||
{
|
||||
++text;
|
||||
}
|
||||
|
||||
if (*text == '\0')
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
end = text + strlen(text) - 1u;
|
||||
while ((end > text) && isspace((unsigned char)*end))
|
||||
{
|
||||
*end = '\0';
|
||||
--end;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
static void profile_repository_copy_string(char *destination, size_t destination_size, const char *source)
|
||||
{
|
||||
if ((destination == NULL) || (destination_size == 0u))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (source == NULL)
|
||||
{
|
||||
destination[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(destination, source, destination_size - 1u);
|
||||
destination[destination_size - 1u] = '\0';
|
||||
}
|
||||
|
||||
static bool profile_repository_parse_bool(const char *value, bool *out_value)
|
||||
{
|
||||
if ((value == NULL) || (out_value == NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((strcmp(value, "1") == 0) || (strcasecmp(value, "true") == 0) || (strcasecmp(value, "yes") == 0))
|
||||
{
|
||||
*out_value = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((strcmp(value, "0") == 0) || (strcasecmp(value, "false") == 0) || (strcasecmp(value, "no") == 0))
|
||||
{
|
||||
*out_value = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint16_t profile_repository_parse_u16(const char *value)
|
||||
{
|
||||
return (uint16_t)strtoul(value, NULL, 0);
|
||||
}
|
||||
|
||||
static uint32_t profile_repository_parse_u32(const char *value)
|
||||
{
|
||||
return (uint32_t)strtoul(value, NULL, 0);
|
||||
}
|
||||
|
||||
static float profile_repository_parse_float(const char *value)
|
||||
{
|
||||
return strtof(value, NULL);
|
||||
}
|
||||
|
||||
static void profile_repository_reset_profile(profile_t *profile)
|
||||
{
|
||||
memset(profile, 0, sizeof(*profile));
|
||||
profile->auto_run = true;
|
||||
profile->boot_enabled = true;
|
||||
profile->waveform.mode = WAVEFORM_MODE_SAW;
|
||||
profile->waveform.enabled = 1u;
|
||||
profile->waveform.saw_step = 1u;
|
||||
profile->waveform.pat_period_base = 2u;
|
||||
profile->waveform.pat_period = 0xFFFFu;
|
||||
profile->waveform.sample_count = AD9102_SRAM_DEFAULT_SAMPLE_COUNT;
|
||||
profile->waveform.hold_cycles = AD9102_SRAM_DEFAULT_HOLD;
|
||||
profile->waveform.amplitude = AD9102_SRAM_DEFAULT_AMPLITUDE;
|
||||
profile->tec_modulation.enabled = 0u;
|
||||
profile->tec_modulation.channel_index = 0u;
|
||||
profile->tec_modulation.frequency_hz = 1000u;
|
||||
profile->tec_modulation.amplitude_code = 0u;
|
||||
profile->ds1809.apply_position = false;
|
||||
}
|
||||
|
||||
static void profile_repository_apply_key_value(profile_t *profile, const char *key, const char *value)
|
||||
{
|
||||
bool bool_value;
|
||||
|
||||
if ((profile == NULL) || (key == NULL) || (value == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(key, "profile_name") == 0)
|
||||
{
|
||||
profile_repository_copy_string(profile->display_name, sizeof(profile->display_name), value);
|
||||
}
|
||||
else if (strcmp(key, "auto_run") == 0)
|
||||
{
|
||||
if (profile_repository_parse_bool(value, &bool_value))
|
||||
{
|
||||
profile->auto_run = bool_value;
|
||||
}
|
||||
}
|
||||
else if (strcmp(key, "boot_enabled") == 0)
|
||||
{
|
||||
if (profile_repository_parse_bool(value, &bool_value))
|
||||
{
|
||||
profile->boot_enabled = bool_value;
|
||||
}
|
||||
}
|
||||
else if (strcmp(key, "work_enable") == 0)
|
||||
{
|
||||
profile->work_config.work_enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "u5v1_enable") == 0)
|
||||
{
|
||||
profile->work_config.supply_5v1_enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "u5v2_enable") == 0)
|
||||
{
|
||||
profile->work_config.supply_5v2_enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "ld1_enable") == 0)
|
||||
{
|
||||
profile->work_config.laser1_enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "ld2_enable") == 0)
|
||||
{
|
||||
profile->work_config.laser2_enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "ref1_enable") == 0)
|
||||
{
|
||||
profile->work_config.reference1_enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "ref2_enable") == 0)
|
||||
{
|
||||
profile->work_config.reference2_enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "tec1_enable") == 0)
|
||||
{
|
||||
profile->work_config.tec1_enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "tec2_enable") == 0)
|
||||
{
|
||||
profile->work_config.tec2_enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "ts1_enable") == 0)
|
||||
{
|
||||
profile->work_config.temp_sensor1_enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "ts2_enable") == 0)
|
||||
{
|
||||
profile->work_config.temp_sensor2_enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "pid1_from_host") == 0)
|
||||
{
|
||||
profile->work_config.pid1_from_host = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "pid2_from_host") == 0)
|
||||
{
|
||||
profile->work_config.pid2_from_host = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "averages") == 0)
|
||||
{
|
||||
profile->work_config.averages = profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "message_id") == 0)
|
||||
{
|
||||
profile->work_config.message_id = profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "laser1_target_temp") == 0)
|
||||
{
|
||||
profile->laser_channels[0].target_temperature_raw = profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "laser2_target_temp") == 0)
|
||||
{
|
||||
profile->laser_channels[1].target_temperature_raw = profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "laser1_current") == 0)
|
||||
{
|
||||
profile->laser_channels[0].current_raw = profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "laser2_current") == 0)
|
||||
{
|
||||
profile->laser_channels[1].current_raw = profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "laser1_pid_p") == 0)
|
||||
{
|
||||
profile->laser_channels[0].pid_p = profile_repository_parse_float(value);
|
||||
}
|
||||
else if (strcmp(key, "laser1_pid_i") == 0)
|
||||
{
|
||||
profile->laser_channels[0].pid_i = profile_repository_parse_float(value);
|
||||
}
|
||||
else if (strcmp(key, "laser2_pid_p") == 0)
|
||||
{
|
||||
profile->laser_channels[1].pid_p = profile_repository_parse_float(value);
|
||||
}
|
||||
else if (strcmp(key, "laser2_pid_i") == 0)
|
||||
{
|
||||
profile->laser_channels[1].pid_i = profile_repository_parse_float(value);
|
||||
}
|
||||
else if (strcmp(key, "waveform_mode") == 0)
|
||||
{
|
||||
if (strcasecmp(value, "saw") == 0)
|
||||
{
|
||||
profile->waveform.mode = WAVEFORM_MODE_SAW;
|
||||
}
|
||||
else if (strcasecmp(value, "generated_sram") == 0)
|
||||
{
|
||||
profile->waveform.mode = WAVEFORM_MODE_SRAM_GENERATED;
|
||||
}
|
||||
else if (strcasecmp(value, "custom_sram") == 0)
|
||||
{
|
||||
profile->waveform.mode = WAVEFORM_MODE_SRAM_CUSTOM;
|
||||
}
|
||||
}
|
||||
else if (strcmp(key, "waveform_enable") == 0)
|
||||
{
|
||||
profile->waveform.enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "waveform_triangle") == 0)
|
||||
{
|
||||
profile->waveform.triangle = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "waveform_saw_step") == 0)
|
||||
{
|
||||
profile->waveform.saw_step = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "waveform_pat_base") == 0)
|
||||
{
|
||||
profile->waveform.pat_period_base = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "waveform_pat_period") == 0)
|
||||
{
|
||||
profile->waveform.pat_period = profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "waveform_sample_count") == 0)
|
||||
{
|
||||
profile->waveform.sample_count = profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "waveform_hold_cycles") == 0)
|
||||
{
|
||||
profile->waveform.hold_cycles = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "waveform_amplitude") == 0)
|
||||
{
|
||||
profile->waveform.amplitude = profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "waveform_source") == 0)
|
||||
{
|
||||
profile_repository_copy_string(profile->waveform.source_path, sizeof(profile->waveform.source_path), value);
|
||||
}
|
||||
else if (strcmp(key, "ad9833_enable") == 0)
|
||||
{
|
||||
profile->ad9833.enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "ad9833_triangle") == 0)
|
||||
{
|
||||
profile->ad9833.triangle = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "ad9833_frequency_word") == 0)
|
||||
{
|
||||
profile->ad9833.frequency_word = profile_repository_parse_u32(value);
|
||||
}
|
||||
else if (strcmp(key, "stm32_dac_enable") == 0)
|
||||
{
|
||||
profile->stm32_dac.enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "stm32_dac_code") == 0)
|
||||
{
|
||||
profile->stm32_dac.code = profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "tec_modulation_enable") == 0)
|
||||
{
|
||||
profile->tec_modulation.enabled = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "tec_modulation_laser") == 0)
|
||||
{
|
||||
uint16_t laser = profile_repository_parse_u16(value);
|
||||
if (laser == 1u)
|
||||
{
|
||||
profile->tec_modulation.channel_index = 0u;
|
||||
}
|
||||
else if (laser == 2u)
|
||||
{
|
||||
profile->tec_modulation.channel_index = 1u;
|
||||
}
|
||||
else
|
||||
{
|
||||
profile->tec_modulation.channel_index = 0xFFu;
|
||||
}
|
||||
}
|
||||
else if (strcmp(key, "tec_modulation_frequency_hz") == 0)
|
||||
{
|
||||
profile->tec_modulation.frequency_hz = profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "tec_modulation_amplitude_code") == 0)
|
||||
{
|
||||
profile->tec_modulation.amplitude_code = profile_repository_parse_u16(value);
|
||||
}
|
||||
else if (strcmp(key, "ds1809_apply") == 0)
|
||||
{
|
||||
if (profile_repository_parse_bool(value, &bool_value))
|
||||
{
|
||||
profile->ds1809.apply_position = bool_value;
|
||||
}
|
||||
}
|
||||
else if (strcmp(key, "ds1809_position_from_min") == 0)
|
||||
{
|
||||
profile->ds1809.position_from_min = (uint8_t)profile_repository_parse_u16(value);
|
||||
}
|
||||
}
|
||||
|
||||
static bool profile_repository_load_ini_file(const char *profile_path, profile_t *profile)
|
||||
{
|
||||
char buffer[PROFILE_REPOSITORY_BUFFER_SIZE];
|
||||
UINT bytes_read = 0u;
|
||||
char *cursor;
|
||||
FRESULT result;
|
||||
|
||||
result = storage_sd_read_bytes(profile_path, 0u, buffer, sizeof(buffer) - 1u, &bytes_read);
|
||||
if (result != FR_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer[bytes_read] = '\0';
|
||||
cursor = buffer;
|
||||
|
||||
while (*cursor != '\0')
|
||||
{
|
||||
char *line_start = cursor;
|
||||
char *line_end = strpbrk(cursor, "\r\n");
|
||||
char *separator;
|
||||
char *key;
|
||||
char *value;
|
||||
|
||||
if (line_end != NULL)
|
||||
{
|
||||
*line_end = '\0';
|
||||
cursor = line_end + 1;
|
||||
while ((*cursor == '\r') || (*cursor == '\n'))
|
||||
{
|
||||
++cursor;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor += strlen(cursor);
|
||||
}
|
||||
|
||||
line_start = profile_repository_trim(line_start);
|
||||
if ((*line_start == '\0') || (*line_start == '#') || (*line_start == ';'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
separator = strchr(line_start, '=');
|
||||
if (separator == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
*separator = '\0';
|
||||
key = profile_repository_trim(line_start);
|
||||
value = profile_repository_trim(separator + 1);
|
||||
profile_repository_apply_key_value(profile, key, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool profile_repository_load_by_valid_line_index(uint16_t target_index,
|
||||
profile_t *out_profile,
|
||||
uint16_t *out_total_valid_lines)
|
||||
{
|
||||
char buffer[PROFILE_REPOSITORY_BUFFER_SIZE];
|
||||
UINT bytes_read = 0u;
|
||||
char *cursor;
|
||||
uint16_t valid_line_index = 0u;
|
||||
FRESULT result;
|
||||
|
||||
if ((out_profile == NULL) || !storage_sd_file_exists(APP_STORAGE_PROFILE_INDEX_FILE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
result = storage_sd_read_bytes(APP_STORAGE_PROFILE_INDEX_FILE, 0u, buffer, sizeof(buffer) - 1u, &bytes_read);
|
||||
if (result != FR_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer[bytes_read] = '\0';
|
||||
cursor = buffer;
|
||||
|
||||
while (*cursor != '\0')
|
||||
{
|
||||
char *line_start = cursor;
|
||||
char *line_end = strpbrk(cursor, "\r\n");
|
||||
char *display_name;
|
||||
char *profile_path;
|
||||
char *waveform_path;
|
||||
char *separator_1;
|
||||
char *separator_2;
|
||||
|
||||
if (line_end != NULL)
|
||||
{
|
||||
*line_end = '\0';
|
||||
cursor = line_end + 1;
|
||||
while ((*cursor == '\r') || (*cursor == '\n'))
|
||||
{
|
||||
++cursor;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor += strlen(cursor);
|
||||
}
|
||||
|
||||
line_start = profile_repository_trim(line_start);
|
||||
if ((*line_start == '\0') || (*line_start == '#') || (*line_start == ';'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
separator_1 = strchr(line_start, ',');
|
||||
if (separator_1 == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
*separator_1 = '\0';
|
||||
separator_2 = strchr(separator_1 + 1, ',');
|
||||
if (separator_2 != NULL)
|
||||
{
|
||||
*separator_2 = '\0';
|
||||
}
|
||||
|
||||
display_name = profile_repository_trim(line_start);
|
||||
profile_path = profile_repository_trim(separator_1 + 1);
|
||||
waveform_path = (separator_2 != NULL) ? profile_repository_trim(separator_2 + 1) : "";
|
||||
|
||||
if (*profile_path == '\0')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (valid_line_index == target_index)
|
||||
{
|
||||
profile_repository_reset_profile(out_profile);
|
||||
profile_repository_copy_string(out_profile->display_name, sizeof(out_profile->display_name), display_name);
|
||||
profile_repository_copy_string(out_profile->profile_path, sizeof(out_profile->profile_path), profile_path);
|
||||
profile_repository_copy_string(out_profile->waveform_path, sizeof(out_profile->waveform_path), waveform_path);
|
||||
profile_repository_copy_string(out_profile->waveform.source_path,
|
||||
sizeof(out_profile->waveform.source_path),
|
||||
waveform_path);
|
||||
|
||||
if (!profile_repository_load_ini_file(profile_path, out_profile))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (out_total_valid_lines != NULL)
|
||||
{
|
||||
*out_total_valid_lines = (uint16_t)(valid_line_index + 1u);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
++valid_line_index;
|
||||
}
|
||||
|
||||
if (out_total_valid_lines != NULL)
|
||||
{
|
||||
*out_total_valid_lines = valid_line_index;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool profile_repository_load_first(profile_t *out_profile, uint16_t *out_index)
|
||||
{
|
||||
uint16_t total_lines = 0u;
|
||||
|
||||
if (!profile_repository_load_by_valid_line_index(0u, out_profile, &total_lines))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (out_index != NULL)
|
||||
{
|
||||
*out_index = 0u;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool profile_repository_load_next(uint16_t *in_out_index, profile_t *out_profile)
|
||||
{
|
||||
uint16_t requested_index;
|
||||
uint16_t total_lines = 0u;
|
||||
|
||||
if ((in_out_index == NULL) || (out_profile == NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
requested_index = (uint16_t)(*in_out_index + 1u);
|
||||
if (profile_repository_load_by_valid_line_index(requested_index, out_profile, &total_lines))
|
||||
{
|
||||
*in_out_index = requested_index;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((total_lines == 0u) || !profile_repository_load_by_valid_line_index(0u, out_profile, NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*in_out_index = 0u;
|
||||
return true;
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
/**
|
||||
* @file profile_repository.h
|
||||
* @brief Future SD-card profile repository with minimal standalone parsing.
|
||||
*/
|
||||
|
||||
#ifndef PROFILE_REPOSITORY_H
|
||||
#define PROFILE_REPOSITORY_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "app_types.h"
|
||||
|
||||
/**
|
||||
* @brief Load the first valid profile listed in `profiles.csv`.
|
||||
*
|
||||
* @param out_profile Destination profile object.
|
||||
* @param out_index Receives the zero-based valid profile index.
|
||||
*
|
||||
* @retval true A valid profile was loaded.
|
||||
* @retval false No valid profile entry was available.
|
||||
*/
|
||||
bool profile_repository_load_first(profile_t *out_profile, uint16_t *out_index);
|
||||
|
||||
/**
|
||||
* @brief Load the next valid profile, wrapping around to the first entry.
|
||||
*
|
||||
* @param in_out_index Current profile index on input, next index on success.
|
||||
* @param out_profile Destination profile object.
|
||||
*
|
||||
* @retval true The next valid profile was loaded.
|
||||
* @retval false No valid profile entry was available.
|
||||
*/
|
||||
bool profile_repository_load_next(uint16_t *in_out_index, profile_t *out_profile);
|
||||
|
||||
#endif /* PROFILE_REPOSITORY_H */
|
||||
@ -1,497 +0,0 @@
|
||||
/**
|
||||
* @file profile_storage.c
|
||||
* @brief Streamed SD-card writer for GUI-initiated profile saves.
|
||||
*/
|
||||
|
||||
#include "profile_storage.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "app_types.h"
|
||||
#include "storage_sd.h"
|
||||
|
||||
#define PROFILE_STORAGE_PROFILES_DIR "profiles"
|
||||
#define PROFILE_STORAGE_WAVES_DIR "waves"
|
||||
#define PROFILE_STORAGE_PROFILE_FILE_TEMPLATE "profiles/PROF%04u.INI"
|
||||
#define PROFILE_STORAGE_WAVE_FILE_TEMPLATE "waves/WAVE%04u.CSV"
|
||||
#define PROFILE_STORAGE_MAX_FILE_INDEX 9999u
|
||||
#define PROFILE_STORAGE_INDEX_LINE_BUFFER_SIZE 192u
|
||||
|
||||
typedef struct profile_storage_context_t {
|
||||
bool active;
|
||||
bool profile_file_open;
|
||||
bool waveform_file_open;
|
||||
char display_name[APP_PROFILE_NAME_LENGTH];
|
||||
char profile_path[APP_PROFILE_PATH_LENGTH];
|
||||
char waveform_path[APP_PROFILE_PATH_LENGTH];
|
||||
uint16_t profile_expected_bytes;
|
||||
uint16_t waveform_expected_bytes;
|
||||
uint16_t profile_received_bytes;
|
||||
uint16_t waveform_received_bytes;
|
||||
FIL profile_file;
|
||||
FIL waveform_file;
|
||||
profile_storage_status_t last_status;
|
||||
} profile_storage_context_t;
|
||||
|
||||
static profile_storage_context_t g_profile_storage;
|
||||
|
||||
static profile_storage_status_t profile_storage_set_status(profile_storage_status_t status)
|
||||
{
|
||||
g_profile_storage.last_status = status;
|
||||
return status;
|
||||
}
|
||||
|
||||
static void profile_storage_reset_context(void)
|
||||
{
|
||||
memset(&g_profile_storage, 0, sizeof(g_profile_storage));
|
||||
g_profile_storage.last_status = PROFILE_STORAGE_STATUS_OK;
|
||||
}
|
||||
|
||||
static bool profile_storage_is_name_character_allowed(char character)
|
||||
{
|
||||
return (isalnum((unsigned char)character) != 0) ||
|
||||
(character == ' ') ||
|
||||
(character == '-') ||
|
||||
(character == '_');
|
||||
}
|
||||
|
||||
static bool profile_storage_copy_validated_name(char *destination, size_t destination_size, const char *source)
|
||||
{
|
||||
const char *start;
|
||||
const char *end;
|
||||
size_t length;
|
||||
size_t index;
|
||||
|
||||
if ((destination == NULL) || (destination_size < APP_PROFILE_NAME_LENGTH) || (source == NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
start = source;
|
||||
while ((*start != '\0') && isspace((unsigned char)*start))
|
||||
{
|
||||
++start;
|
||||
}
|
||||
|
||||
end = start + strlen(start);
|
||||
while ((end > start) && isspace((unsigned char)end[-1]))
|
||||
{
|
||||
--end;
|
||||
}
|
||||
|
||||
length = (size_t)(end - start);
|
||||
if ((length == 0u) || (length > APP_PROFILE_NAME_MAX_CHARACTERS))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (index = 0u; index < length; ++index)
|
||||
{
|
||||
if (!profile_storage_is_name_character_allowed(start[index]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(destination, start, length);
|
||||
destination[length] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
static void profile_storage_clear_session_paths(void)
|
||||
{
|
||||
g_profile_storage.display_name[0] = '\0';
|
||||
g_profile_storage.profile_path[0] = '\0';
|
||||
g_profile_storage.waveform_path[0] = '\0';
|
||||
}
|
||||
|
||||
static void profile_storage_close_open_files(void)
|
||||
{
|
||||
if (g_profile_storage.waveform_file_open)
|
||||
{
|
||||
(void)storage_sd_close_file(&g_profile_storage.waveform_file);
|
||||
g_profile_storage.waveform_file_open = false;
|
||||
}
|
||||
|
||||
if (g_profile_storage.profile_file_open)
|
||||
{
|
||||
(void)storage_sd_close_file(&g_profile_storage.profile_file);
|
||||
g_profile_storage.profile_file_open = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void profile_storage_remove_partial_files(void)
|
||||
{
|
||||
if (g_profile_storage.waveform_path[0] != '\0')
|
||||
{
|
||||
(void)storage_sd_remove_file(g_profile_storage.waveform_path);
|
||||
}
|
||||
|
||||
if (g_profile_storage.profile_path[0] != '\0')
|
||||
{
|
||||
(void)storage_sd_remove_file(g_profile_storage.profile_path);
|
||||
}
|
||||
}
|
||||
|
||||
static void profile_storage_abort_session(void)
|
||||
{
|
||||
profile_storage_close_open_files();
|
||||
profile_storage_remove_partial_files();
|
||||
g_profile_storage.active = false;
|
||||
g_profile_storage.profile_expected_bytes = 0u;
|
||||
g_profile_storage.waveform_expected_bytes = 0u;
|
||||
g_profile_storage.profile_received_bytes = 0u;
|
||||
g_profile_storage.waveform_received_bytes = 0u;
|
||||
profile_storage_clear_session_paths();
|
||||
}
|
||||
|
||||
static profile_storage_status_t profile_storage_format_target_path(char *destination,
|
||||
size_t destination_size,
|
||||
const char *format_string,
|
||||
uint16_t file_index)
|
||||
{
|
||||
int written;
|
||||
|
||||
written = snprintf(destination, destination_size, format_string, (unsigned int)file_index);
|
||||
if ((written <= 0) || ((size_t)written >= destination_size))
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_FILE_NAME_EXHAUSTED);
|
||||
}
|
||||
|
||||
return PROFILE_STORAGE_STATUS_OK;
|
||||
}
|
||||
|
||||
static profile_storage_status_t profile_storage_find_free_paths(uint16_t waveform_text_bytes)
|
||||
{
|
||||
uint16_t file_index;
|
||||
|
||||
for (file_index = 1u; file_index <= PROFILE_STORAGE_MAX_FILE_INDEX; ++file_index)
|
||||
{
|
||||
FILINFO file_info;
|
||||
FRESULT result;
|
||||
profile_storage_status_t status;
|
||||
|
||||
status = profile_storage_format_target_path(g_profile_storage.profile_path,
|
||||
sizeof(g_profile_storage.profile_path),
|
||||
PROFILE_STORAGE_PROFILE_FILE_TEMPLATE,
|
||||
file_index);
|
||||
if (status != PROFILE_STORAGE_STATUS_OK)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
result = storage_sd_stat(g_profile_storage.profile_path, &file_info);
|
||||
if (result == FR_OK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((result != FR_NO_FILE) && (result != FR_NO_PATH))
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_STORAGE_UNAVAILABLE);
|
||||
}
|
||||
|
||||
if (waveform_text_bytes > 0u)
|
||||
{
|
||||
status = profile_storage_format_target_path(g_profile_storage.waveform_path,
|
||||
sizeof(g_profile_storage.waveform_path),
|
||||
PROFILE_STORAGE_WAVE_FILE_TEMPLATE,
|
||||
file_index);
|
||||
if (status != PROFILE_STORAGE_STATUS_OK)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
result = storage_sd_stat(g_profile_storage.waveform_path, &file_info);
|
||||
if (result == FR_OK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((result != FR_NO_FILE) && (result != FR_NO_PATH))
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_STORAGE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_profile_storage.waveform_path[0] = '\0';
|
||||
}
|
||||
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_OK);
|
||||
}
|
||||
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_FILE_NAME_EXHAUSTED);
|
||||
}
|
||||
|
||||
static profile_storage_status_t profile_storage_open_target_files(void)
|
||||
{
|
||||
FRESULT result;
|
||||
|
||||
result = storage_sd_make_directory(PROFILE_STORAGE_PROFILES_DIR);
|
||||
if (result != FR_OK)
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_DIRECTORY_ERROR);
|
||||
}
|
||||
|
||||
if (g_profile_storage.waveform_expected_bytes > 0u)
|
||||
{
|
||||
result = storage_sd_make_directory(PROFILE_STORAGE_WAVES_DIR);
|
||||
if (result != FR_OK)
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_DIRECTORY_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
result = storage_sd_open_file(&g_profile_storage.profile_file,
|
||||
g_profile_storage.profile_path,
|
||||
FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (result != FR_OK)
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_FILE_OPEN_ERROR);
|
||||
}
|
||||
g_profile_storage.profile_file_open = true;
|
||||
|
||||
if (g_profile_storage.waveform_expected_bytes > 0u)
|
||||
{
|
||||
result = storage_sd_open_file(&g_profile_storage.waveform_file,
|
||||
g_profile_storage.waveform_path,
|
||||
FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (result != FR_OK)
|
||||
{
|
||||
profile_storage_abort_session();
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_FILE_OPEN_ERROR);
|
||||
}
|
||||
g_profile_storage.waveform_file_open = true;
|
||||
}
|
||||
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_OK);
|
||||
}
|
||||
|
||||
static profile_storage_status_t profile_storage_write_to_file(FIL *file,
|
||||
uint16_t *received_bytes,
|
||||
uint16_t expected_bytes,
|
||||
const uint8_t *data,
|
||||
uint16_t data_size)
|
||||
{
|
||||
UINT bytes_written = 0u;
|
||||
FRESULT result;
|
||||
|
||||
if ((file == NULL) || (received_bytes == NULL) || (data == NULL) || (data_size == 0u))
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
if ((uint32_t)(*received_bytes) + (uint32_t)data_size > (uint32_t)expected_bytes)
|
||||
{
|
||||
profile_storage_abort_session();
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_SIZE_MISMATCH);
|
||||
}
|
||||
|
||||
result = f_write(file, data, data_size, &bytes_written);
|
||||
if ((result != FR_OK) || (bytes_written != data_size))
|
||||
{
|
||||
profile_storage_abort_session();
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_WRITE_ERROR);
|
||||
}
|
||||
|
||||
*received_bytes = (uint16_t)(*received_bytes + data_size);
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_OK);
|
||||
}
|
||||
|
||||
static profile_storage_status_t profile_storage_append_index_entry(void)
|
||||
{
|
||||
char line_buffer[PROFILE_STORAGE_INDEX_LINE_BUFFER_SIZE];
|
||||
FIL index_file;
|
||||
UINT bytes_written = 0u;
|
||||
FRESULT result;
|
||||
int line_length;
|
||||
|
||||
line_length = snprintf(line_buffer,
|
||||
sizeof(line_buffer),
|
||||
"%s,%s,%s\r\n",
|
||||
g_profile_storage.display_name,
|
||||
g_profile_storage.profile_path,
|
||||
g_profile_storage.waveform_path);
|
||||
if ((line_length <= 0) || ((size_t)line_length >= sizeof(line_buffer)))
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_INDEX_UPDATE_ERROR);
|
||||
}
|
||||
|
||||
result = storage_sd_open_file(&index_file,
|
||||
APP_STORAGE_PROFILE_INDEX_FILE,
|
||||
FA_OPEN_ALWAYS | FA_WRITE);
|
||||
if (result != FR_OK)
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_INDEX_UPDATE_ERROR);
|
||||
}
|
||||
|
||||
result = f_lseek(&index_file, f_size(&index_file));
|
||||
if (result == FR_OK)
|
||||
{
|
||||
result = f_write(&index_file, line_buffer, (UINT)line_length, &bytes_written);
|
||||
}
|
||||
if (result == FR_OK)
|
||||
{
|
||||
result = f_sync(&index_file);
|
||||
}
|
||||
|
||||
(void)storage_sd_close_file(&index_file);
|
||||
|
||||
if ((result != FR_OK) || (bytes_written != (UINT)line_length))
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_INDEX_UPDATE_ERROR);
|
||||
}
|
||||
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_OK);
|
||||
}
|
||||
|
||||
void profile_storage_init(void)
|
||||
{
|
||||
profile_storage_reset_context();
|
||||
}
|
||||
|
||||
bool profile_storage_is_active(void)
|
||||
{
|
||||
return g_profile_storage.active;
|
||||
}
|
||||
|
||||
profile_storage_status_t profile_storage_get_last_status(void)
|
||||
{
|
||||
return g_profile_storage.last_status;
|
||||
}
|
||||
|
||||
profile_storage_status_t profile_storage_begin(const char *display_name,
|
||||
uint16_t profile_text_bytes,
|
||||
uint16_t waveform_text_bytes)
|
||||
{
|
||||
if (profile_storage_is_active())
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_SESSION_ACTIVE);
|
||||
}
|
||||
|
||||
profile_storage_reset_context();
|
||||
|
||||
if (!storage_sd_is_available())
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_STORAGE_UNAVAILABLE);
|
||||
}
|
||||
|
||||
if ((profile_text_bytes == 0u) || !profile_storage_copy_validated_name(g_profile_storage.display_name,
|
||||
sizeof(g_profile_storage.display_name),
|
||||
display_name))
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_NAME_INVALID);
|
||||
}
|
||||
|
||||
g_profile_storage.profile_expected_bytes = profile_text_bytes;
|
||||
g_profile_storage.waveform_expected_bytes = waveform_text_bytes;
|
||||
g_profile_storage.active = true;
|
||||
|
||||
if (profile_storage_find_free_paths(waveform_text_bytes) != PROFILE_STORAGE_STATUS_OK)
|
||||
{
|
||||
g_profile_storage.active = false;
|
||||
return g_profile_storage.last_status;
|
||||
}
|
||||
|
||||
if (profile_storage_open_target_files() != PROFILE_STORAGE_STATUS_OK)
|
||||
{
|
||||
g_profile_storage.active = false;
|
||||
profile_storage_clear_session_paths();
|
||||
return g_profile_storage.last_status;
|
||||
}
|
||||
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_OK);
|
||||
}
|
||||
|
||||
profile_storage_status_t profile_storage_write_chunk(uint16_t section_id,
|
||||
const uint8_t *data,
|
||||
uint16_t data_size)
|
||||
{
|
||||
if (!g_profile_storage.active)
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_NO_ACTIVE_SESSION);
|
||||
}
|
||||
|
||||
if ((data == NULL) || (data_size == 0u) || (data_size > APP_PROFILE_SAVE_MAX_DATA_BYTES_PER_PACKET))
|
||||
{
|
||||
profile_storage_abort_session();
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
if (section_id == APP_PROFILE_SAVE_SECTION_PROFILE_TEXT)
|
||||
{
|
||||
return profile_storage_write_to_file(&g_profile_storage.profile_file,
|
||||
&g_profile_storage.profile_received_bytes,
|
||||
g_profile_storage.profile_expected_bytes,
|
||||
data,
|
||||
data_size);
|
||||
}
|
||||
|
||||
if ((section_id == APP_PROFILE_SAVE_SECTION_WAVEFORM_TEXT) && g_profile_storage.waveform_file_open)
|
||||
{
|
||||
return profile_storage_write_to_file(&g_profile_storage.waveform_file,
|
||||
&g_profile_storage.waveform_received_bytes,
|
||||
g_profile_storage.waveform_expected_bytes,
|
||||
data,
|
||||
data_size);
|
||||
}
|
||||
|
||||
profile_storage_abort_session();
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_SECTION_ERROR);
|
||||
}
|
||||
|
||||
profile_storage_status_t profile_storage_commit(void)
|
||||
{
|
||||
if (!g_profile_storage.active)
|
||||
{
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_NO_ACTIVE_SESSION);
|
||||
}
|
||||
|
||||
if ((g_profile_storage.profile_received_bytes != g_profile_storage.profile_expected_bytes) ||
|
||||
(g_profile_storage.waveform_received_bytes != g_profile_storage.waveform_expected_bytes))
|
||||
{
|
||||
profile_storage_abort_session();
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_SIZE_MISMATCH);
|
||||
}
|
||||
|
||||
if (g_profile_storage.profile_file_open && (f_sync(&g_profile_storage.profile_file) != FR_OK))
|
||||
{
|
||||
profile_storage_abort_session();
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_WRITE_ERROR);
|
||||
}
|
||||
|
||||
if (g_profile_storage.waveform_file_open && (f_sync(&g_profile_storage.waveform_file) != FR_OK))
|
||||
{
|
||||
profile_storage_abort_session();
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_WRITE_ERROR);
|
||||
}
|
||||
|
||||
profile_storage_close_open_files();
|
||||
|
||||
if (profile_storage_append_index_entry() != PROFILE_STORAGE_STATUS_OK)
|
||||
{
|
||||
profile_storage_remove_partial_files();
|
||||
g_profile_storage.active = false;
|
||||
profile_storage_clear_session_paths();
|
||||
return g_profile_storage.last_status;
|
||||
}
|
||||
|
||||
g_profile_storage.active = false;
|
||||
g_profile_storage.profile_expected_bytes = 0u;
|
||||
g_profile_storage.waveform_expected_bytes = 0u;
|
||||
g_profile_storage.profile_received_bytes = 0u;
|
||||
g_profile_storage.waveform_received_bytes = 0u;
|
||||
profile_storage_clear_session_paths();
|
||||
return profile_storage_set_status(PROFILE_STORAGE_STATUS_OK);
|
||||
}
|
||||
|
||||
void profile_storage_cancel(void)
|
||||
{
|
||||
if (g_profile_storage.active)
|
||||
{
|
||||
profile_storage_abort_session();
|
||||
}
|
||||
|
||||
g_profile_storage.last_status = PROFILE_STORAGE_STATUS_OK;
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
/**
|
||||
* @file profile_storage.h
|
||||
* @brief Streamed SD-card writer for GUI-initiated profile saves.
|
||||
*
|
||||
* Architectural note:
|
||||
* The desktop GUI already knows the current human-facing configuration values.
|
||||
* It serialises them into the same INI/CSV text format that standalone boot
|
||||
* understands, while this service owns the SD-card side: validating the
|
||||
* profile name, generating 8.3-compatible file names, streaming incoming text
|
||||
* into files, and updating `profiles.csv` only after the full upload succeeds.
|
||||
*/
|
||||
|
||||
#ifndef PROFILE_STORAGE_H
|
||||
#define PROFILE_STORAGE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Result codes returned by the streamed profile-save service.
|
||||
*/
|
||||
typedef enum profile_storage_status_t {
|
||||
PROFILE_STORAGE_STATUS_OK = 0,
|
||||
PROFILE_STORAGE_STATUS_INVALID_ARGUMENT,
|
||||
PROFILE_STORAGE_STATUS_NAME_INVALID,
|
||||
PROFILE_STORAGE_STATUS_STORAGE_UNAVAILABLE,
|
||||
PROFILE_STORAGE_STATUS_SESSION_ACTIVE,
|
||||
PROFILE_STORAGE_STATUS_NO_ACTIVE_SESSION,
|
||||
PROFILE_STORAGE_STATUS_DIRECTORY_ERROR,
|
||||
PROFILE_STORAGE_STATUS_FILE_NAME_EXHAUSTED,
|
||||
PROFILE_STORAGE_STATUS_FILE_OPEN_ERROR,
|
||||
PROFILE_STORAGE_STATUS_WRITE_ERROR,
|
||||
PROFILE_STORAGE_STATUS_INDEX_UPDATE_ERROR,
|
||||
PROFILE_STORAGE_STATUS_SIZE_MISMATCH,
|
||||
PROFILE_STORAGE_STATUS_SECTION_ERROR
|
||||
} profile_storage_status_t;
|
||||
|
||||
void profile_storage_init(void);
|
||||
bool profile_storage_is_active(void);
|
||||
profile_storage_status_t profile_storage_get_last_status(void);
|
||||
profile_storage_status_t profile_storage_begin(const char *display_name,
|
||||
uint16_t profile_text_bytes,
|
||||
uint16_t waveform_text_bytes);
|
||||
profile_storage_status_t profile_storage_write_chunk(uint16_t section_id,
|
||||
const uint8_t *data,
|
||||
uint16_t data_size);
|
||||
profile_storage_status_t profile_storage_commit(void);
|
||||
void profile_storage_cancel(void);
|
||||
|
||||
#endif /* PROFILE_STORAGE_H */
|
||||
@ -1,214 +0,0 @@
|
||||
/**
|
||||
* @file storage_sd.c
|
||||
* @brief Narrow SD-card storage wrapper built directly on FatFs.
|
||||
*/
|
||||
|
||||
#include "storage_sd.h"
|
||||
|
||||
#include "fatfs.h"
|
||||
|
||||
#include "board_io.h"
|
||||
|
||||
static uint8_t g_storage_mounted = 0u;
|
||||
static uint16_t g_storage_mount_depth = 0u;
|
||||
|
||||
bool storage_sd_is_available(void)
|
||||
{
|
||||
return board_io_is_sd_card_present();
|
||||
}
|
||||
|
||||
FRESULT storage_sd_begin(void)
|
||||
{
|
||||
FRESULT result;
|
||||
|
||||
if (!storage_sd_is_available())
|
||||
{
|
||||
return FR_NOT_READY;
|
||||
}
|
||||
|
||||
if (g_storage_mount_depth > 0u)
|
||||
{
|
||||
++g_storage_mount_depth;
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
result = f_mount(&SDFatFS, SDPath, 1u);
|
||||
if (result == FR_OK)
|
||||
{
|
||||
g_storage_mounted = 1u;
|
||||
g_storage_mount_depth = 1u;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FRESULT storage_sd_end(void)
|
||||
{
|
||||
FRESULT result;
|
||||
|
||||
if (g_storage_mount_depth == 0u)
|
||||
{
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
--g_storage_mount_depth;
|
||||
if (g_storage_mount_depth > 0u)
|
||||
{
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
result = f_mount(NULL, SDPath, 1u);
|
||||
if (result == FR_OK)
|
||||
{
|
||||
g_storage_mounted = 0u;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_storage_mount_depth = 1u;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FRESULT storage_sd_open_file(FIL *file, const char *path, BYTE mode)
|
||||
{
|
||||
FRESULT result;
|
||||
|
||||
if ((file == NULL) || (path == NULL))
|
||||
{
|
||||
return FR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
result = storage_sd_begin();
|
||||
if (result != FR_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = f_open(file, path, mode);
|
||||
if (result != FR_OK)
|
||||
{
|
||||
(void)storage_sd_end();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FRESULT storage_sd_close_file(FIL *file)
|
||||
{
|
||||
FRESULT close_result = FR_OK;
|
||||
FRESULT end_result;
|
||||
|
||||
if (file != NULL)
|
||||
{
|
||||
close_result = f_close(file);
|
||||
}
|
||||
|
||||
end_result = storage_sd_end();
|
||||
if (close_result != FR_OK)
|
||||
{
|
||||
return close_result;
|
||||
}
|
||||
|
||||
return end_result;
|
||||
}
|
||||
|
||||
FRESULT storage_sd_read_bytes(const char *path, FSIZE_t offset, void *data, UINT size, UINT *bytes_read)
|
||||
{
|
||||
FIL file;
|
||||
UINT local_bytes_read = 0u;
|
||||
FRESULT result = storage_sd_open_file(&file, path, FA_READ);
|
||||
|
||||
if (result != FR_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = f_lseek(&file, offset);
|
||||
if (result == FR_OK)
|
||||
{
|
||||
result = f_read(&file, data, size, &local_bytes_read);
|
||||
}
|
||||
(void)storage_sd_close_file(&file);
|
||||
|
||||
if (bytes_read != NULL)
|
||||
{
|
||||
*bytes_read = local_bytes_read;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FRESULT storage_sd_stat(const char *path, FILINFO *out_info)
|
||||
{
|
||||
FRESULT result;
|
||||
|
||||
if (path == NULL)
|
||||
{
|
||||
return FR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
result = storage_sd_begin();
|
||||
if (result != FR_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = f_stat(path, out_info);
|
||||
(void)storage_sd_end();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool storage_sd_file_exists(const char *path)
|
||||
{
|
||||
FILINFO info;
|
||||
return storage_sd_stat(path, &info) == FR_OK;
|
||||
}
|
||||
|
||||
FRESULT storage_sd_make_directory(const char *path)
|
||||
{
|
||||
FRESULT result;
|
||||
|
||||
if (path == NULL)
|
||||
{
|
||||
return FR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
result = storage_sd_begin();
|
||||
if (result != FR_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = f_mkdir(path);
|
||||
if (result == FR_EXIST)
|
||||
{
|
||||
result = FR_OK;
|
||||
}
|
||||
(void)storage_sd_end();
|
||||
return result;
|
||||
}
|
||||
|
||||
FRESULT storage_sd_remove_file(const char *path)
|
||||
{
|
||||
FRESULT result;
|
||||
|
||||
if (path == NULL)
|
||||
{
|
||||
return FR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
result = storage_sd_begin();
|
||||
if (result != FR_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = f_unlink(path);
|
||||
if ((result == FR_NO_FILE) || (result == FR_NO_PATH))
|
||||
{
|
||||
result = FR_OK;
|
||||
}
|
||||
(void)storage_sd_end();
|
||||
return result;
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
/**
|
||||
* @file storage_sd.h
|
||||
* @brief Narrow SD-card storage wrapper built directly on FatFs.
|
||||
*
|
||||
* Architectural note:
|
||||
* An earlier storage layer mixed allocation-heavy tutorial helpers with
|
||||
* application-specific policies. This service now exposes only the minimal
|
||||
* file-oriented operations needed by profile loading and streamed profile
|
||||
* saving, while keeping FatFs details out of higher-level services.
|
||||
*/
|
||||
|
||||
#ifndef STORAGE_SD_H
|
||||
#define STORAGE_SD_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
bool storage_sd_is_available(void);
|
||||
FRESULT storage_sd_begin(void);
|
||||
FRESULT storage_sd_end(void);
|
||||
FRESULT storage_sd_read_bytes(const char *path, FSIZE_t offset, void *data, UINT size, UINT *bytes_read);
|
||||
FRESULT storage_sd_open_file(FIL *file, const char *path, BYTE mode);
|
||||
FRESULT storage_sd_close_file(FIL *file);
|
||||
FRESULT storage_sd_stat(const char *path, FILINFO *out_info);
|
||||
bool storage_sd_file_exists(const char *path);
|
||||
FRESULT storage_sd_make_directory(const char *path);
|
||||
FRESULT storage_sd_remove_file(const char *path);
|
||||
|
||||
#endif /* STORAGE_SD_H */
|
||||
@ -1,88 +0,0 @@
|
||||
/**
|
||||
* @file telemetry.c
|
||||
* @brief Telemetry-frame creation, checksum finalisation, and serialisation.
|
||||
*/
|
||||
|
||||
#include "telemetry.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "app_uart_protocol.h"
|
||||
|
||||
void telemetry_reset(telemetry_frame_t *frame)
|
||||
{
|
||||
if (frame == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memset(frame->words, 0, sizeof(frame->words));
|
||||
frame->words[0] = APP_PACKET_HEADER_WORK_CONFIG;
|
||||
}
|
||||
|
||||
void telemetry_set_message_id(telemetry_frame_t *frame, uint16_t message_id)
|
||||
{
|
||||
if (frame != NULL)
|
||||
{
|
||||
frame->words[13] = message_id;
|
||||
}
|
||||
}
|
||||
|
||||
void telemetry_set_live_data(telemetry_frame_t *frame,
|
||||
uint16_t laser1_power,
|
||||
uint16_t laser2_power,
|
||||
uint16_t input_pf3_raw,
|
||||
uint16_t input_pf4_raw,
|
||||
uint16_t laser1_temperature,
|
||||
uint16_t laser2_temperature,
|
||||
uint16_t external_temperature_1_raw,
|
||||
uint16_t external_temperature_2_raw,
|
||||
uint16_t rail_3v3_raw,
|
||||
uint16_t rail_5v1_raw,
|
||||
uint16_t rail_5v2_raw,
|
||||
uint16_t rail_7v0_raw)
|
||||
{
|
||||
if (frame == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
frame->words[1] = laser1_power;
|
||||
frame->words[2] = laser2_power;
|
||||
frame->words[3] = input_pf3_raw;
|
||||
frame->words[4] = input_pf4_raw;
|
||||
frame->words[5] = laser1_temperature;
|
||||
frame->words[6] = laser2_temperature;
|
||||
frame->words[7] = external_temperature_1_raw;
|
||||
frame->words[8] = external_temperature_2_raw;
|
||||
frame->words[9] = rail_3v3_raw;
|
||||
frame->words[10] = rail_5v1_raw;
|
||||
frame->words[11] = rail_5v2_raw;
|
||||
frame->words[12] = rail_7v0_raw;
|
||||
}
|
||||
|
||||
void telemetry_finalize(telemetry_frame_t *frame)
|
||||
{
|
||||
if (frame == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
frame->words[14] = app_protocol_calculate_checksum(&frame->words[1], 13u);
|
||||
}
|
||||
|
||||
void telemetry_to_bytes(const telemetry_frame_t *frame, uint8_t *out_bytes)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
if ((frame == NULL) || (out_bytes == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (index = 0u; index < APP_TELEMETRY_WORD_COUNT; ++index)
|
||||
{
|
||||
out_bytes[index * 2u] = (uint8_t)(frame->words[index] & 0x00FFu);
|
||||
out_bytes[(index * 2u) + 1u] = (uint8_t)((frame->words[index] >> 8) & 0x00FFu);
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
/**
|
||||
* @file telemetry.h
|
||||
* @brief Telemetry-frame creation, checksum finalisation, and serialisation.
|
||||
*/
|
||||
|
||||
#ifndef TELEMETRY_H
|
||||
#define TELEMETRY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "app_types.h"
|
||||
|
||||
void telemetry_reset(telemetry_frame_t *frame);
|
||||
void telemetry_set_message_id(telemetry_frame_t *frame, uint16_t message_id);
|
||||
void telemetry_set_live_data(telemetry_frame_t *frame,
|
||||
uint16_t laser1_power,
|
||||
uint16_t laser2_power,
|
||||
uint16_t input_pf3_raw,
|
||||
uint16_t input_pf4_raw,
|
||||
uint16_t laser1_temperature,
|
||||
uint16_t laser2_temperature,
|
||||
uint16_t external_temperature_1_raw,
|
||||
uint16_t external_temperature_2_raw,
|
||||
uint16_t rail_3v3_raw,
|
||||
uint16_t rail_5v1_raw,
|
||||
uint16_t rail_5v2_raw,
|
||||
uint16_t rail_7v0_raw);
|
||||
void telemetry_finalize(telemetry_frame_t *frame);
|
||||
void telemetry_to_bytes(const telemetry_frame_t *frame, uint8_t *out_bytes);
|
||||
|
||||
#endif /* TELEMETRY_H */
|
||||
@ -1,67 +0,0 @@
|
||||
/**
|
||||
* @file temperature_control.c
|
||||
* @brief Temperature-control services for the laser TEC loops.
|
||||
*/
|
||||
|
||||
#include "temperature_control.h"
|
||||
|
||||
uint16_t temperature_control_compute_pid(const laser_channel_config_t *channel_config,
|
||||
laser_runtime_t *runtime_state,
|
||||
uint8_t channel_index,
|
||||
uint32_t current_tick_1ms,
|
||||
uint32_t *shared_pid_reference_tick)
|
||||
{
|
||||
int32_t error;
|
||||
float proportional_gain;
|
||||
float integral_term;
|
||||
int32_t output;
|
||||
|
||||
if ((channel_config == NULL) || (runtime_state == NULL) || (shared_pid_reference_tick == NULL))
|
||||
{
|
||||
return 32768u;
|
||||
}
|
||||
|
||||
error = (int32_t)runtime_state->current_temperature_raw - (int32_t)channel_config->target_temperature_raw;
|
||||
integral_term = runtime_state->integral_error;
|
||||
|
||||
if ((error < 3000) && (error > -3000))
|
||||
{
|
||||
integral_term += channel_config->pid_i *
|
||||
(float)error *
|
||||
(float)(current_tick_1ms - *shared_pid_reference_tick) /
|
||||
100.0f;
|
||||
}
|
||||
|
||||
proportional_gain = channel_config->pid_p;
|
||||
|
||||
if (integral_term > 32000.0f)
|
||||
{
|
||||
integral_term = 32000.0f;
|
||||
}
|
||||
else if (integral_term < -32000.0f)
|
||||
{
|
||||
integral_term = -32000.0f;
|
||||
}
|
||||
|
||||
runtime_state->integral_error = integral_term;
|
||||
|
||||
output = 32768 + (int32_t)(proportional_gain * (float)error) + (int32_t)integral_term;
|
||||
|
||||
if (output < 1000)
|
||||
{
|
||||
output = 8800;
|
||||
}
|
||||
else if (output > 56800)
|
||||
{
|
||||
output = 56800;
|
||||
}
|
||||
|
||||
/* Both PID channels use a shared timing reference updated after the
|
||||
* second TEC computation. This preserves the original controller timing. */
|
||||
if (channel_index == 2u)
|
||||
{
|
||||
*shared_pid_reference_tick = current_tick_1ms;
|
||||
}
|
||||
|
||||
return (uint16_t)output;
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
/**
|
||||
* @file temperature_control.h
|
||||
* @brief Temperature-control services for the laser TEC loops.
|
||||
*/
|
||||
|
||||
#ifndef TEMPERATURE_CONTROL_H
|
||||
#define TEMPERATURE_CONTROL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "app_types.h"
|
||||
|
||||
uint16_t temperature_control_compute_pid(const laser_channel_config_t *channel_config,
|
||||
laser_runtime_t *runtime_state,
|
||||
uint8_t channel_index,
|
||||
uint32_t current_tick_1ms,
|
||||
uint32_t *shared_pid_reference_tick);
|
||||
|
||||
#endif /* TEMPERATURE_CONTROL_H */
|
||||
@ -1,244 +0,0 @@
|
||||
/**
|
||||
* @file ui_status.c
|
||||
* @brief Standalone LCD/button frontend for profile-driven operation.
|
||||
*
|
||||
* Architectural note:
|
||||
* This service owns all user-facing status formatting and button debouncing.
|
||||
* The application core pushes state into this module, while this module
|
||||
* returns high-level events such as "select next profile".
|
||||
*/
|
||||
|
||||
#include "ui_status.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "board_io.h"
|
||||
#include "lcd1602_display.h"
|
||||
|
||||
#define UI_STATUS_LCD_COLUMNS 16u
|
||||
#define UI_STATUS_BUTTON_DEBOUNCE_TICKS_10MS 3u
|
||||
|
||||
typedef struct ui_button_state_t {
|
||||
bool raw_pressed;
|
||||
bool stable_pressed;
|
||||
uint32_t last_change_tick_10ms;
|
||||
} ui_button_state_t;
|
||||
|
||||
static char g_profile_name[APP_PROFILE_NAME_LENGTH];
|
||||
static app_mode_t g_mode = APP_MODE_IDLE;
|
||||
static uint8_t g_error_flags = 0u;
|
||||
static uint8_t g_initialised = 0u;
|
||||
static uint8_t g_display_dirty = 0u;
|
||||
static ui_button_state_t g_button = {false, false, 0u};
|
||||
|
||||
static void ui_status_mark_dirty(void);
|
||||
static void ui_status_copy_padded(char *destination, const char *source);
|
||||
static const char *ui_status_mode_name(app_mode_t mode);
|
||||
static void ui_status_build_line_1(char *line_buffer);
|
||||
static void ui_status_build_line_2(char *line_buffer);
|
||||
static void ui_status_refresh_display(void);
|
||||
|
||||
void ui_status_init(void)
|
||||
{
|
||||
bool raw_pressed;
|
||||
|
||||
memset(g_profile_name, 0, sizeof(g_profile_name));
|
||||
g_mode = APP_MODE_IDLE;
|
||||
g_error_flags = 0u;
|
||||
|
||||
board_io_init_standalone_ui();
|
||||
raw_pressed = board_io_is_standalone_ui_button_pressed();
|
||||
|
||||
/*
|
||||
* Synchronise the debounce state with the physical input level at boot.
|
||||
* This prevents a stuck-low or already-held button from generating a
|
||||
* synthetic "next profile" event immediately after startup.
|
||||
*/
|
||||
g_button.raw_pressed = raw_pressed;
|
||||
g_button.stable_pressed = raw_pressed;
|
||||
g_button.last_change_tick_10ms = 0u;
|
||||
|
||||
lcd1602_display_init();
|
||||
|
||||
g_initialised = 1u;
|
||||
g_display_dirty = 1u;
|
||||
ui_status_refresh_display();
|
||||
}
|
||||
|
||||
void ui_status_set_profile_name(const char *profile_name)
|
||||
{
|
||||
char next_name[APP_PROFILE_NAME_LENGTH] = {0};
|
||||
|
||||
if (profile_name != NULL)
|
||||
{
|
||||
strncpy(next_name, profile_name, sizeof(next_name) - 1u);
|
||||
}
|
||||
|
||||
if (strncmp(g_profile_name, next_name, sizeof(g_profile_name)) != 0)
|
||||
{
|
||||
memcpy(g_profile_name, next_name, sizeof(g_profile_name));
|
||||
ui_status_mark_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
void ui_status_set_mode(app_mode_t mode)
|
||||
{
|
||||
/*
|
||||
* TX_CURRENT is a transient transport state rather than a user-visible
|
||||
* operating mode. Ignoring it prevents needless LCD churn during polling.
|
||||
*/
|
||||
if (mode == APP_MODE_TX_CURRENT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_mode != mode)
|
||||
{
|
||||
g_mode = mode;
|
||||
ui_status_mark_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
void ui_status_set_error(uint8_t error_flags)
|
||||
{
|
||||
if (g_error_flags != error_flags)
|
||||
{
|
||||
g_error_flags = error_flags;
|
||||
ui_status_mark_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
app_event_t ui_status_poll_event(uint32_t tick_10ms)
|
||||
{
|
||||
bool raw_pressed;
|
||||
app_event_t event = APP_EVENT_NONE;
|
||||
|
||||
if (g_initialised == 0u)
|
||||
{
|
||||
return APP_EVENT_NONE;
|
||||
}
|
||||
|
||||
raw_pressed = board_io_is_standalone_ui_button_pressed();
|
||||
|
||||
if (raw_pressed != g_button.raw_pressed)
|
||||
{
|
||||
g_button.raw_pressed = raw_pressed;
|
||||
g_button.last_change_tick_10ms = tick_10ms;
|
||||
}
|
||||
else if ((tick_10ms - g_button.last_change_tick_10ms) >= UI_STATUS_BUTTON_DEBOUNCE_TICKS_10MS)
|
||||
{
|
||||
if (g_button.stable_pressed != g_button.raw_pressed)
|
||||
{
|
||||
g_button.stable_pressed = g_button.raw_pressed;
|
||||
if (g_button.stable_pressed)
|
||||
{
|
||||
event = APP_EVENT_PROFILE_NEXT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_display_dirty != 0u)
|
||||
{
|
||||
ui_status_refresh_display();
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
static void ui_status_mark_dirty(void)
|
||||
{
|
||||
g_display_dirty = 1u;
|
||||
}
|
||||
|
||||
static void ui_status_copy_padded(char *destination, const char *source)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
for (index = 0u; index < UI_STATUS_LCD_COLUMNS; ++index)
|
||||
{
|
||||
destination[index] = ' ';
|
||||
}
|
||||
destination[UI_STATUS_LCD_COLUMNS] = '\0';
|
||||
|
||||
if (source == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (index = 0u; (index < UI_STATUS_LCD_COLUMNS) && (source[index] != '\0'); ++index)
|
||||
{
|
||||
destination[index] = source[index];
|
||||
}
|
||||
}
|
||||
|
||||
static const char *ui_status_mode_name(app_mode_t mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case APP_MODE_WORK:
|
||||
return "WORK";
|
||||
|
||||
case APP_MODE_ERROR:
|
||||
return "ERROR";
|
||||
|
||||
case APP_MODE_IDLE:
|
||||
default:
|
||||
return "IDLE";
|
||||
}
|
||||
}
|
||||
|
||||
static void ui_status_build_line_1(char *line_buffer)
|
||||
{
|
||||
const char *label = g_profile_name;
|
||||
|
||||
if (line_buffer == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (label[0] == '\0')
|
||||
{
|
||||
label = (g_mode == APP_MODE_WORK) ? "Manual control" : "No profile";
|
||||
}
|
||||
|
||||
ui_status_copy_padded(line_buffer, label);
|
||||
}
|
||||
|
||||
static void ui_status_build_line_2(char *line_buffer)
|
||||
{
|
||||
char status_text[UI_STATUS_LCD_COLUMNS + 1u];
|
||||
|
||||
if (line_buffer == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_error_flags == 0u)
|
||||
{
|
||||
(void)snprintf(status_text, sizeof(status_text), "%s OK", ui_status_mode_name(g_mode));
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)snprintf(status_text, sizeof(status_text), "%s ERR %02X", ui_status_mode_name(g_mode), g_error_flags);
|
||||
}
|
||||
|
||||
ui_status_copy_padded(line_buffer, status_text);
|
||||
}
|
||||
|
||||
static void ui_status_refresh_display(void)
|
||||
{
|
||||
char line_1[UI_STATUS_LCD_COLUMNS + 1u];
|
||||
char line_2[UI_STATUS_LCD_COLUMNS + 1u];
|
||||
|
||||
if (g_initialised == 0u)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ui_status_build_line_1(line_1);
|
||||
ui_status_build_line_2(line_2);
|
||||
lcd1602_display_set_lines(line_1, line_2);
|
||||
g_display_dirty = 0u;
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
/**
|
||||
* @file ui_status.h
|
||||
* @brief Future LCD/UI abstraction used by standalone profile mode.
|
||||
*/
|
||||
|
||||
#ifndef UI_STATUS_H
|
||||
#define UI_STATUS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "app_types.h"
|
||||
|
||||
void ui_status_init(void);
|
||||
void ui_status_set_profile_name(const char *profile_name);
|
||||
void ui_status_set_mode(app_mode_t mode);
|
||||
void ui_status_set_error(uint8_t error_flags);
|
||||
app_event_t ui_status_poll_event(uint32_t tick_10ms);
|
||||
|
||||
#endif /* UI_STATUS_H */
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,74 +0,0 @@
|
||||
SD card example layout
|
||||
|
||||
Firmware expects a plain FAT volume handled by FatFs. In this project `exFAT` is disabled in [ffconf.h](/home/europa/Desktop/RadioPhotonic_PCB_software/Inc/ffconf.h:213), so the safe choice is `FAT32` with a standard MBR partition.
|
||||
|
||||
Recommended card preparation:
|
||||
|
||||
1. Format the card as `FAT32`.
|
||||
2. Copy the files from this directory to the root of the SD card, or keep the same relative folder structure.
|
||||
3. Make sure `profiles.csv` is present at the root path expected by the firmware.
|
||||
|
||||
Expected file set:
|
||||
|
||||
- `profiles.csv`
|
||||
- `profiles/profile_1_saw.ini`
|
||||
- `profiles/profile_2_custom_wave.ini`
|
||||
- `waves/wave_custom.csv`
|
||||
|
||||
`profiles.csv` format:
|
||||
|
||||
- One profile per line.
|
||||
- Columns: `display_name, profile_ini_path, optional_waveform_csv_path`
|
||||
- Empty lines are ignored.
|
||||
- Lines starting with `#` or `;` are ignored.
|
||||
|
||||
Example:
|
||||
|
||||
```csv
|
||||
Factory Saw,profiles/profile_1_saw.ini,
|
||||
Custom SRAM,profiles/profile_2_custom_wave.ini,waves/wave_custom.csv
|
||||
```
|
||||
|
||||
Profile `.ini` format:
|
||||
|
||||
- One `key=value` pair per line.
|
||||
- Empty lines are ignored.
|
||||
- Lines starting with `#` or `;` are ignored.
|
||||
- Unknown keys are ignored.
|
||||
|
||||
Additional profile-controlled devices:
|
||||
|
||||
- `AD9102` waveform settings are stored through the `waveform_*` keys.
|
||||
- `AD9833` settings are stored through `ad9833_enable`, `ad9833_triangle`, and `ad9833_frequency_word`.
|
||||
- STM32 internal DAC settings are stored through `stm32_dac_enable` and `stm32_dac_code`.
|
||||
- TEC drive modulation is stored through `tec_modulation_enable`, `tec_modulation_laser`,
|
||||
`tec_modulation_frequency_hz`, and `tec_modulation_amplitude_code`.
|
||||
- `DS1809` is stored as an absolute target above the minimum tap using `ds1809_apply` and `ds1809_position_from_min`.
|
||||
|
||||
Notes:
|
||||
|
||||
- `ad9833_frequency_word` uses the same raw 28-bit tuning word that the old serial command accepted.
|
||||
- `tec_modulation_laser` is `1` or `2`; accepted TEC modulation frequency is `50..2000 Hz`,
|
||||
and peak amplitude is `0..4096` external TEC DAC codes.
|
||||
- `ds1809_position_from_min` is clamped to the valid `0..63` range by the firmware.
|
||||
- When `ds1809_apply=true`, the firmware first drives the potentiometer fully down and then steps it up to the requested absolute position.
|
||||
|
||||
Waveform file format:
|
||||
|
||||
- The firmware scans the file with `strtol()`.
|
||||
- Any integer token found in the file becomes one AD9102 SRAM sample.
|
||||
- Separators may be commas, spaces, tabs, or newlines.
|
||||
- Do not put comments or stray digits into the waveform file, because any parsed integer will be treated as a sample.
|
||||
|
||||
Supported `waveform_mode` values:
|
||||
|
||||
- `saw`
|
||||
- `generated_sram`
|
||||
- `custom_sram`
|
||||
|
||||
Minimal boot behavior:
|
||||
|
||||
- On startup the firmware loads the first valid line from `profiles.csv`.
|
||||
- It then loads the referenced profile `.ini`.
|
||||
- If `boot_enabled=true`, the profile is activated.
|
||||
- If `auto_run=true`, the board immediately enters `WORK` mode.
|
||||
@ -1,3 +0,0 @@
|
||||
# display_name, profile_ini_path, optional_waveform_csv_path
|
||||
Factory Saw,profiles/prof1.ini,
|
||||
Custom SRAM,profiles/prof2.ini,waves/wave1.csv
|
||||
|
@ -1,52 +0,0 @@
|
||||
# Profile 1: standard saw waveform, immediate boot and auto-run.
|
||||
profile_name=Factory Saw
|
||||
boot_enabled=true
|
||||
auto_run=true
|
||||
|
||||
work_enable=1
|
||||
u5v1_enable=1
|
||||
u5v2_enable=1
|
||||
ld1_enable=1
|
||||
ld2_enable=1
|
||||
ref1_enable=1
|
||||
ref2_enable=1
|
||||
tec1_enable=1
|
||||
tec2_enable=1
|
||||
ts1_enable=1
|
||||
ts2_enable=1
|
||||
|
||||
pid1_from_host=1
|
||||
pid2_from_host=1
|
||||
averages=16
|
||||
message_id=100
|
||||
|
||||
laser1_target_temp=2500
|
||||
laser2_target_temp=2520
|
||||
laser1_current=1200
|
||||
laser2_current=1180
|
||||
laser1_pid_p=10.0
|
||||
laser1_pid_i=0.01
|
||||
laser2_pid_p=10.0
|
||||
laser2_pid_i=0.01
|
||||
|
||||
waveform_mode=saw
|
||||
waveform_enable=1
|
||||
waveform_triangle=0
|
||||
waveform_saw_step=4
|
||||
waveform_pat_base=2
|
||||
waveform_pat_period=65535
|
||||
|
||||
ad9833_enable=0
|
||||
ad9833_triangle=0
|
||||
ad9833_frequency_word=0
|
||||
|
||||
stm32_dac_enable=0
|
||||
stm32_dac_code=0
|
||||
|
||||
tec_modulation_enable=0
|
||||
tec_modulation_laser=1
|
||||
tec_modulation_frequency_hz=1000
|
||||
tec_modulation_amplitude_code=0
|
||||
|
||||
ds1809_apply=true
|
||||
ds1809_position_from_min=0
|
||||
@ -1,56 +0,0 @@
|
||||
# Profile 2: custom waveform loaded from a separate CSV file.
|
||||
profile_name=Custom SRAM
|
||||
boot_enabled=true
|
||||
auto_run=true
|
||||
|
||||
work_enable=1
|
||||
u5v1_enable=1
|
||||
u5v2_enable=1
|
||||
ld1_enable=1
|
||||
ld2_enable=0
|
||||
ref1_enable=1
|
||||
ref2_enable=0
|
||||
tec1_enable=1
|
||||
tec2_enable=0
|
||||
ts1_enable=1
|
||||
ts2_enable=0
|
||||
|
||||
pid1_from_host=1
|
||||
pid2_from_host=1
|
||||
averages=16
|
||||
message_id=200
|
||||
|
||||
laser1_target_temp=2480
|
||||
laser2_target_temp=0
|
||||
laser1_current=1350
|
||||
laser2_current=0
|
||||
laser1_pid_p=9.5
|
||||
laser1_pid_i=0.02
|
||||
laser2_pid_p=0.0
|
||||
laser2_pid_i=0.0
|
||||
|
||||
waveform_mode=custom_sram
|
||||
waveform_enable=1
|
||||
waveform_triangle=0
|
||||
waveform_saw_step=1
|
||||
waveform_pat_base=2
|
||||
waveform_pat_period=65535
|
||||
waveform_sample_count=16
|
||||
waveform_hold_cycles=8
|
||||
waveform_amplitude=4095
|
||||
waveform_source=waves/wave1.csv
|
||||
|
||||
ad9833_enable=1
|
||||
ad9833_triangle=0
|
||||
ad9833_frequency_word=0x00123456
|
||||
|
||||
stm32_dac_enable=1
|
||||
stm32_dac_code=2048
|
||||
|
||||
tec_modulation_enable=0
|
||||
tec_modulation_laser=1
|
||||
tec_modulation_frequency_hz=1000
|
||||
tec_modulation_amplitude_code=0
|
||||
|
||||
ds1809_apply=true
|
||||
ds1809_position_from_min=18
|
||||
@ -1,16 +0,0 @@
|
||||
0,
|
||||
512,
|
||||
1024,
|
||||
1536,
|
||||
2048,
|
||||
3072,
|
||||
4095,
|
||||
3072,
|
||||
2048,
|
||||
1024,
|
||||
0,
|
||||
-1024,
|
||||
-2048,
|
||||
-1024,
|
||||
0,
|
||||
512
|
||||
|
Can't render this file because it has a wrong number of fields in line 16.
|
@ -89,7 +89,7 @@ Mcu.Pin0=PF3
|
||||
Mcu.Pin1=PF4
|
||||
Mcu.Pin10=PC0
|
||||
Mcu.Pin11=PC1
|
||||
Mcu.Pin12=PC7
|
||||
Mcu.Pin12=PC2
|
||||
Mcu.Pin13=PC3
|
||||
Mcu.Pin14=PA0/WKUP
|
||||
Mcu.Pin15=PA1
|
||||
@ -166,13 +166,8 @@ Mcu.Pin79=VP_TIM8_VS_ClockSourceINT
|
||||
Mcu.Pin8=PH0/OSC_IN
|
||||
Mcu.Pin80=VP_TIM10_VS_ClockSourceINT
|
||||
Mcu.Pin81=VP_TIM11_VS_ClockSourceINT
|
||||
Mcu.Pin82=PD12
|
||||
Mcu.Pin83=PD13
|
||||
Mcu.Pin84=PE2
|
||||
Mcu.Pin85=PE3
|
||||
Mcu.Pin86=PE8
|
||||
Mcu.Pin9=PH1/OSC_OUT
|
||||
Mcu.PinsNb=87
|
||||
Mcu.PinsNb=82
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32F767ZITx
|
||||
@ -220,10 +215,11 @@ PA3.GPIOParameters=GPIO_Label
|
||||
PA3.GPIO_Label=REF2_ON
|
||||
PA3.Locked=true
|
||||
PA3.Signal=GPIO_Output
|
||||
PA4.GPIOParameters=GPIO_Label
|
||||
PA4.GPIO_Label=PA4_DAC_OUT
|
||||
PA4.GPIOParameters=PinState,GPIO_Label
|
||||
PA4.GPIO_Label=DAC_TEC2_CS
|
||||
PA4.Locked=true
|
||||
PA4.Signal=DACx_OUT1
|
||||
PA4.PinState=GPIO_PIN_SET
|
||||
PA4.Signal=GPIO_Output
|
||||
PA5.Locked=true
|
||||
PA5.Mode=TX_Only_Simplex_Unidirect_Master
|
||||
PA5.Signal=SPI6_SCK
|
||||
@ -254,7 +250,7 @@ PB11.GPIO_Label=TEC1_PD
|
||||
PB11.Locked=true
|
||||
PB11.Signal=GPIO_Output
|
||||
PB12.GPIOParameters=PinState,GPIO_Label
|
||||
PB12.GPIO_Label=AD9102_CS
|
||||
PB12.GPIO_Label=DAC_TEC1_CS
|
||||
PB12.Locked=true
|
||||
PB12.PinState=GPIO_PIN_SET
|
||||
PB12.Signal=GPIO_Output
|
||||
@ -300,10 +296,10 @@ PC11.Mode=SD_4_bits_Wide_bus
|
||||
PC11.Signal=SDMMC1_D3
|
||||
PC12.Mode=SD_4_bits_Wide_bus
|
||||
PC12.Signal=SDMMC1_CK
|
||||
PC7.GPIOParameters=GPIO_Label
|
||||
PC7.GPIO_Label=EN_5V2
|
||||
PC7.Locked=true
|
||||
PC7.Signal=GPIO_Output
|
||||
PC2.GPIOParameters=GPIO_Label
|
||||
PC2.GPIO_Label=EN_5V2
|
||||
PC2.Locked=true
|
||||
PC2.Signal=GPIO_Output
|
||||
PC3.GPIOParameters=GPIO_Speed,GPIO_Label
|
||||
PC3.GPIO_Label=EN_5V1
|
||||
PC3.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
@ -329,16 +325,6 @@ PD1.GPIOParameters=GPIO_Label
|
||||
PD1.GPIO_Label=TEST_01
|
||||
PD1.Locked=true
|
||||
PD1.Signal=GPIO_Output
|
||||
PD12.GPIOParameters=PinState,GPIO_Label
|
||||
PD12.GPIO_Label=DAC_TEC1_CS
|
||||
PD12.Locked=true
|
||||
PD12.PinState=GPIO_PIN_SET
|
||||
PD12.Signal=GPIO_Output
|
||||
PD13.GPIOParameters=PinState,GPIO_Label
|
||||
PD13.GPIO_Label=AD9833_CS
|
||||
PD13.Locked=true
|
||||
PD13.PinState=GPIO_PIN_SET
|
||||
PD13.Signal=GPIO_Output
|
||||
PD2.Mode=SD_4_bits_Wide_bus
|
||||
PD2.Signal=SDMMC1_CMD
|
||||
PD7.Locked=true
|
||||
@ -353,21 +339,6 @@ PE0.Signal=UART8_RX
|
||||
PE1.Locked=true
|
||||
PE1.Mode=Asynchronous
|
||||
PE1.Signal=UART8_TX
|
||||
PE2.GPIOParameters=PinState,GPIO_Label
|
||||
PE2.GPIO_Label=DS1809_UC
|
||||
PE2.Locked=true
|
||||
PE2.PinState=GPIO_PIN_SET
|
||||
PE2.Signal=GPIO_Output
|
||||
PE3.GPIOParameters=PinState,GPIO_Label
|
||||
PE3.GPIO_Label=DS1809_DC
|
||||
PE3.Locked=true
|
||||
PE3.PinState=GPIO_PIN_SET
|
||||
PE3.Signal=GPIO_Output
|
||||
PE8.GPIOParameters=PinState,GPIO_Label
|
||||
PE8.GPIO_Label=DAC_TEC2_CS
|
||||
PE8.Locked=true
|
||||
PE8.PinState=GPIO_PIN_SET
|
||||
PE8.Signal=GPIO_Output
|
||||
PE10.GPIOParameters=GPIO_Label
|
||||
PE10.GPIO_Label=ADC_MPD1_CS
|
||||
PE10.Locked=true
|
||||
@ -582,8 +553,8 @@ SH.S_TIM11_CH1.ConfNb=1
|
||||
SH.S_TIM4_CH3.0=TIM4_CH3,PWM Generation3 CH3
|
||||
SH.S_TIM4_CH3.ConfNb=1
|
||||
SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_8
|
||||
SPI2.CLKPhase=SPI_PHASE_1EDGE
|
||||
SPI2.CLKPolarity=SPI_POLARITY_LOW
|
||||
SPI2.CLKPhase=SPI_PHASE_2EDGE
|
||||
SPI2.CLKPolarity=SPI_POLARITY_HIGH
|
||||
SPI2.CalculateBaudRate=5.75 MBits/s
|
||||
SPI2.DataSize=SPI_DATASIZE_16BIT
|
||||
SPI2.Direction=SPI_DIRECTION_2LINES
|
||||
|
||||
69
Inc/File_Handling.h
Normal file
69
Inc/File_Handling.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* File_Handling_RTOS.h
|
||||
*
|
||||
* Created on: 14-May-2020
|
||||
* Author: Controllerstech
|
||||
*/
|
||||
|
||||
#ifndef FILE_HANDLING_RTOS_H_
|
||||
#define FILE_HANDLING_RTOS_H_
|
||||
|
||||
#include "fatfs.h"
|
||||
#include <string.h>
|
||||
#include "stdio.h"
|
||||
#include "fatfs.h"
|
||||
|
||||
|
||||
/* mounts the sd card*/
|
||||
int Mount_SD (const TCHAR* path);
|
||||
|
||||
/* unmounts the sd card*/
|
||||
int Unmount_SD (const TCHAR* path);
|
||||
|
||||
/* Start node to be scanned (***also used as work area***) */
|
||||
FRESULT Scan_SD (char* pat);
|
||||
|
||||
/* Only supports removing files from home directory. Directory remover to be added soon */
|
||||
FRESULT Format_SD (void);
|
||||
|
||||
/* write the data to the file
|
||||
* @ name : is the path to the file*/
|
||||
FRESULT Write_File (char *name, char *data);
|
||||
|
||||
/* write the data to the file
|
||||
* @ name : is the path to the file tooooooooooooooooooooooooooooooooooooooooooooooooo*/
|
||||
FRESULT Write_File_byte (char *name, uint8_t *data, unsigned int bytesize);
|
||||
|
||||
/* read data from the file
|
||||
* @ name : is the path to the file*/
|
||||
FRESULT Read_File (char *name);
|
||||
|
||||
FRESULT Seek_Read_File (char *name, uint8_t *data, unsigned int bytesize, unsigned long goto_label);
|
||||
|
||||
/* creates the file, if it does not exists
|
||||
* @ name : is the path to the file*/
|
||||
FRESULT Create_File (char *name);
|
||||
|
||||
/* Removes the file from the sd card
|
||||
* @ name : is the path to the file*/
|
||||
FRESULT Remove_File (char *name);
|
||||
|
||||
/* creates a directory
|
||||
* @ name: is the path to the directory
|
||||
*/
|
||||
FRESULT Create_Dir (char *name);
|
||||
|
||||
/* checks the free space in the sd card*/
|
||||
void Check_SD_Space (void);
|
||||
|
||||
/* updates the file. write pointer is set to the end of the file
|
||||
* @ name : is the path to the file
|
||||
*/
|
||||
FRESULT Update_File (char *name, char *data);
|
||||
|
||||
FRESULT Update_File_float (char *name, float *data, unsigned int bytesize);
|
||||
|
||||
FRESULT Update_File_byte (char *name, uint8_t *data, unsigned int bytesize);
|
||||
|
||||
|
||||
#endif /* FILE_HANDLING_RTOS_H_ */
|
||||
@ -62,15 +62,6 @@
|
||||
#else
|
||||
/* USER CODE BEGIN BSP_H_CODE */
|
||||
|
||||
typedef struct bsp_sd_debug_info_t
|
||||
{
|
||||
uint8_t last_init_status;
|
||||
uint8_t last_detect_status;
|
||||
uint8_t last_hal_init_status;
|
||||
uint8_t last_wide_bus_status;
|
||||
uint32_t last_hal_error;
|
||||
} bsp_sd_debug_info_t;
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
uint8_t BSP_SD_Init(void);
|
||||
uint8_t BSP_SD_ITConfig(void);
|
||||
@ -88,7 +79,6 @@ uint8_t BSP_SD_IsDetected(void);
|
||||
void BSP_SD_AbortCallback(void);
|
||||
void BSP_SD_WriteCpltCallback(void);
|
||||
void BSP_SD_ReadCpltCallback(void);
|
||||
void BSP_SD_GetDebugInfo(bsp_sd_debug_info_t *out_info);
|
||||
/* USER CODE END BSP_H_CODE */
|
||||
#endif
|
||||
|
||||
|
||||
155
Inc/main.h
155
Inc/main.h
@ -68,6 +68,10 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void Error_Handler(void);
|
||||
|
||||
/* USER CODE BEGIN EFP */
|
||||
void Set_LTEC(uint8_t, uint16_t);
|
||||
/* USER CODE END EFP */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#define INP_0_Pin GPIO_PIN_3
|
||||
#define INP_0_GPIO_Port GPIOF
|
||||
@ -79,20 +83,18 @@ void Error_Handler(void);
|
||||
#define SPI5_CNV_GPIO_Port GPIOF
|
||||
#define ADC_ThrLD2_CS_Pin GPIO_PIN_10
|
||||
#define ADC_ThrLD2_CS_GPIO_Port GPIOF
|
||||
#define EN_5V2_Pin GPIO_PIN_7
|
||||
#define EN_5V2_Pin GPIO_PIN_2
|
||||
#define EN_5V2_GPIO_Port GPIOC
|
||||
#define EN_5V1_Pin GPIO_PIN_3
|
||||
#define EN_5V1_GPIO_Port GPIOC
|
||||
#define AD9102_RESET_Pin GPIO_PIN_6
|
||||
#define AD9102_RESET_GPIO_Port GPIOC
|
||||
#define TECEN1_Pin GPIO_PIN_0
|
||||
#define TECEN1_GPIO_Port GPIOA
|
||||
#define TECEN2_Pin GPIO_PIN_1
|
||||
#define TECEN2_GPIO_Port GPIOA
|
||||
#define REF2_ON_Pin GPIO_PIN_3
|
||||
#define REF2_ON_GPIO_Port GPIOA
|
||||
#define DAC_TEC2_CS_Pin GPIO_PIN_8
|
||||
#define DAC_TEC2_CS_GPIO_Port GPIOE
|
||||
#define DAC_TEC2_CS_Pin GPIO_PIN_4
|
||||
#define DAC_TEC2_CS_GPIO_Port GPIOA
|
||||
#define DAC_LD2_CS_Pin GPIO_PIN_6
|
||||
#define DAC_LD2_CS_GPIO_Port GPIOA
|
||||
#define LD2_EN_Pin GPIO_PIN_4
|
||||
@ -118,23 +120,11 @@ void Error_Handler(void);
|
||||
#define TEC1_PD_Pin GPIO_PIN_11
|
||||
#define TEC1_PD_GPIO_Port GPIOB
|
||||
#define DAC_TEC1_CS_Pin GPIO_PIN_12
|
||||
#define DAC_TEC1_CS_GPIO_Port GPIOD
|
||||
#define DAC_TEC1_CS_GPIO_Port GPIOB
|
||||
#define DAC_LD1_CS_Pin GPIO_PIN_14
|
||||
#define DAC_LD1_CS_GPIO_Port GPIOB
|
||||
#define LD1_EN_Pin GPIO_PIN_8
|
||||
#define LD1_EN_GPIO_Port GPIOD
|
||||
#define AD9102_CS_Pin GPIO_PIN_12
|
||||
#define AD9102_CS_GPIO_Port GPIOB
|
||||
#define AD9833_CS_Pin GPIO_PIN_13
|
||||
#define AD9833_CS_GPIO_Port GPIOD
|
||||
#define AD9833_MCLK_Pin GPIO_PIN_9
|
||||
#define AD9833_MCLK_GPIO_Port GPIOE
|
||||
#define DS1809_UC_Pin GPIO_PIN_2
|
||||
#define DS1809_UC_GPIO_Port GPIOE
|
||||
#define DS1809_DC_Pin GPIO_PIN_3
|
||||
#define DS1809_DC_GPIO_Port GPIOE
|
||||
#define AD9102_TRIG_Pin GPIO_PIN_11
|
||||
#define AD9102_TRIG_GPIO_Port GPIOD
|
||||
#define USB_FLAG_Pin GPIO_PIN_8
|
||||
#define USB_FLAG_GPIO_Port GPIOA
|
||||
#define SDMMC1_EN_Pin GPIO_PIN_0
|
||||
@ -163,25 +153,116 @@ void Error_Handler(void);
|
||||
#define OUT_9_GPIO_Port GPIOB
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
/* Board-level extensions only. Application-layer types live under App/. */
|
||||
#define UI_LCD_RS_Pin GPIO_PIN_9
|
||||
#define UI_LCD_RS_GPIO_Port GPIOG
|
||||
#define UI_LCD_V0_REF_Pin GPIO_PIN_7
|
||||
#define UI_LCD_V0_REF_GPIO_Port GPIOD
|
||||
#define UI_LCD_CONTRAST_PWM_Pin GPIO_PIN_8
|
||||
#define UI_LCD_CONTRAST_PWM_GPIO_Port GPIOB
|
||||
#define UI_LCD_E_Pin OUT_0_Pin
|
||||
#define UI_LCD_E_GPIO_Port OUT_0_GPIO_Port
|
||||
#define UI_BUTTON_Pin OUT_1_Pin
|
||||
#define UI_BUTTON_GPIO_Port OUT_1_GPIO_Port
|
||||
#define UI_LCD_D4_Pin OUT_2_Pin
|
||||
#define UI_LCD_D4_GPIO_Port OUT_2_GPIO_Port
|
||||
#define UI_LCD_D5_Pin OUT_3_Pin
|
||||
#define UI_LCD_D5_GPIO_Port OUT_3_GPIO_Port
|
||||
#define UI_LCD_D6_Pin OUT_4_Pin
|
||||
#define UI_LCD_D6_GPIO_Port OUT_4_GPIO_Port
|
||||
#define UI_LCD_D7_Pin OUT_5_Pin
|
||||
#define UI_LCD_D7_GPIO_Port OUT_5_GPIO_Port
|
||||
#define CL_16 15
|
||||
#define DL_16 15
|
||||
#define CL_8 30
|
||||
#define DL_8 30
|
||||
#define TSK_8 32
|
||||
#define TSK_16 16
|
||||
|
||||
|
||||
// #define SD_Length 100
|
||||
|
||||
#define HALT 0
|
||||
#define DECODE_ENABLE 1
|
||||
#define DEFAULT_ENABLE 2
|
||||
#define TRANS_S_ENABLE 3
|
||||
#define TRANS_ENABLE 4
|
||||
#define REMOVE_FILE 5
|
||||
#define STATE 6
|
||||
#define WORK_ENABLE 7
|
||||
#define DECODE_TASK 8
|
||||
#define RUN_TASK 9
|
||||
|
||||
#define SD_ERR 0x01
|
||||
#define UART_ERR 0x02
|
||||
#define UART_DECODE_ERR 0x04
|
||||
#define TEC1_ERR 0x08
|
||||
#define TEC2_ERR 0x10
|
||||
#define DEFAUL_ERR 0x20
|
||||
#define REMOVE_ERR 0x40
|
||||
|
||||
#define NO_MESS 0
|
||||
#define MESS_01 1
|
||||
#define MESS_02 2
|
||||
#define MESS_03 3
|
||||
|
||||
typedef struct{
|
||||
|
||||
uint8_t WORK_EN;
|
||||
uint8_t U5V1_EN;
|
||||
uint8_t U5V2_EN;
|
||||
uint8_t LD1_EN;
|
||||
uint8_t LD2_EN;
|
||||
uint8_t REF1_EN;
|
||||
uint8_t REF2_EN;
|
||||
uint8_t TEC1_EN;
|
||||
uint8_t TEC2_EN;
|
||||
uint8_t TS1_EN;
|
||||
uint8_t TS2_EN;
|
||||
uint8_t SD_EN;
|
||||
uint8_t PI1_RD;
|
||||
uint8_t PI2_RD;
|
||||
|
||||
uint16_t AVERAGES;
|
||||
uint16_t MES_ID;
|
||||
|
||||
}Work_SetupTypeDef;
|
||||
|
||||
typedef struct{
|
||||
|
||||
uint16_t LD_TEMP;
|
||||
float P_coef_temp;
|
||||
float I_coef_temp;
|
||||
uint16_t CURRENT;
|
||||
|
||||
}LDx_SetupTypeDef;
|
||||
|
||||
typedef struct{
|
||||
|
||||
uint16_t LD_CURR_TEMP;
|
||||
float e_integral;
|
||||
uint16_t POWER;
|
||||
|
||||
}LDx_ParamTypeDef;
|
||||
|
||||
typedef enum _task_type_t
|
||||
{
|
||||
TT_CHANGE_CURR_1 = 0x1,
|
||||
TT_CHANGE_CURR_2 = 0x2,
|
||||
TT_CHANGE_TEMP_1 = 0x3,
|
||||
TT_CHANGE_TEMP_2 = 0x4,
|
||||
} task_type_t;
|
||||
|
||||
typedef struct _task_t
|
||||
{
|
||||
task_type_t task_type;
|
||||
float min_param;
|
||||
float max_param;
|
||||
float delta_param; // change step between min_param and max_param
|
||||
float current_param; // current_param is iterating by summary with delta_param every interrupt
|
||||
uint8_t dt; // microseconds
|
||||
uint16_t tau; // milliseconds or microseconds?
|
||||
float sec_param;
|
||||
float curr;
|
||||
float temp;
|
||||
float i_coef_1;
|
||||
float p_coef_1;
|
||||
float i_coef_2;
|
||||
float p_coef_2;
|
||||
} task_t;
|
||||
|
||||
|
||||
typedef struct{
|
||||
task_type_t task_type;
|
||||
uint16_t signal_pin;
|
||||
GPIO_TypeDef * signal_port;
|
||||
uint16_t param;
|
||||
uint8_t state; //0 -- disabled (do nothing);
|
||||
//1 -- update LD current;
|
||||
//2 -- blinking, set LD ON now;
|
||||
//3 -- blinking, set LD OFF now
|
||||
} LD_Blinker_StateTypeDef;
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -28,7 +28,6 @@
|
||||
/* USER CODE END firstSection */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "ff_gen_drv.h"
|
||||
#include "bsp_driver_sd.h"
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
@ -37,8 +36,6 @@ extern const Diskio_drvTypeDef SD_Driver;
|
||||
|
||||
/* USER CODE BEGIN lastSection */
|
||||
/* can be used to modify / undefine previous code or add new definitions */
|
||||
DSTATUS sd_diskio_debug_get_last_initialize_status(void);
|
||||
DSTATUS sd_diskio_debug_get_last_status_result(void);
|
||||
/* USER CODE END lastSection */
|
||||
|
||||
#endif /* __SD_DISKIO_H */
|
||||
|
||||
@ -56,8 +56,11 @@ void DebugMon_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void ADC_IRQHandler(void);
|
||||
void TIM1_UP_TIM10_IRQHandler(void);
|
||||
void TIM1_TRG_COM_TIM11_IRQHandler(void);
|
||||
void TIM2_IRQHandler(void);
|
||||
void USART1_IRQHandler(void);
|
||||
void TIM8_UP_TIM13_IRQHandler(void);
|
||||
void TIM5_IRQHandler(void);
|
||||
void TIM6_DAC_IRQHandler(void);
|
||||
void TIM7_IRQHandler(void);
|
||||
|
||||
77
MDK-ARM/DebugConfig/For_stm32_STM32F767ZITx_2.0.0.dbgconf
Normal file
77
MDK-ARM/DebugConfig/For_stm32_STM32F767ZITx_2.0.0.dbgconf
Normal file
@ -0,0 +1,77 @@
|
||||
// File: STM32F76x_77x.dbgconf
|
||||
// Version: 1.0.0
|
||||
// Note: refer to STM32F76xxx STM32F77xxx reference manual (RM0410)
|
||||
// refer to STM32F76xxx STM32F77xxx datasheets
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <h> Debug MCU configuration register (DBGMCU_CR)
|
||||
// <o.2> DBG_STANDBY <i> Debug standby mode
|
||||
// <o.1> DBG_STOP <i> Debug stop mode
|
||||
// <o.0> DBG_SLEEP <i> Debug sleep mode
|
||||
// </h>
|
||||
DbgMCU_CR = 0x00000007;
|
||||
|
||||
// <h> Debug MCU APB1 freeze register (DBGMCU_APB1_FZ)
|
||||
// <i> Reserved bits must be kept at reset value
|
||||
// <o.26> DBG_CAN2_STOP <i> Debug CAN2 stopped when core is halted
|
||||
// <o.25> DBG_CAN1_STOP <i> Debug CAN1 stopped when core is halted
|
||||
// <o.24> DBG_I2C4_SMBUS_TIMEOUT <i> SMBUS timeout mode stopped when core is halted
|
||||
// <o.23> DBG_I2C3_SMBUS_TIMEOUT <i> SMBUS timeout mode stopped when core is halted
|
||||
// <o.22> DBG_I2C2_SMBUS_TIMEOUT <i> SMBUS timeout mode stopped when core is halted
|
||||
// <o.21> DBG_I2C1_SMBUS_TIMEOUT <i> SMBUS timeout mode stopped when core is halted
|
||||
// <o.13> DBG_CAN3_STOP <i> Debug CAN3 stopped when core is halted
|
||||
// <o.12> DBG_IWDG_STOP <i> Debug independent watchdog stopped when core is halted
|
||||
// <o.11> DBG_WWDG_STOP <i> Debug window watchdog stopped when core is halted
|
||||
// <o.10> DBG_RTC_STOP <i> RTC stopped when core is halted
|
||||
// <o.9> DBG_LPTIM1_STOP <i> LPTMI1 counter stopped when core is halted
|
||||
// <o.8> DBG_TIM14_STOP <i> TIM14 counter stopped when core is halted
|
||||
// <o.7> DBG_TIM13_STOP <i> TIM13 counter stopped when core is halted
|
||||
// <o.6> DBG_TIM12_STOP <i> TIM12 counter stopped when core is halted
|
||||
// <o.5> DBG_TIM7_STOP <i> TIM7 counter stopped when core is halted
|
||||
// <o.4> DBG_TIM6_STOP <i> TIM6 counter stopped when core is halted
|
||||
// <o.3> DBG_TIM5_STOP <i> TIM5 counter stopped when core is halted
|
||||
// <o.2> DBG_TIM4_STOP <i> TIM4 counter stopped when core is halted
|
||||
// <o.1> DBG_TIM3_STOP <i> TIM3 counter stopped when core is halted
|
||||
// <o.0> DBG_TIM2_STOP <i> TIM2 counter stopped when core is halted
|
||||
// </h>
|
||||
DbgMCU_APB1_Fz = 0x00000000;
|
||||
|
||||
// <h> Debug MCU APB2 freeze register (DBGMCU_APB2_FZ)
|
||||
// <i> Reserved bits must be kept at reset value
|
||||
// <o.18> DBG_TIM11_STOP <i> TIM11 counter stopped when core is halted
|
||||
// <o.17> DBG_TIM10_STOP <i> TIM10 counter stopped when core is halted
|
||||
// <o.16> DBG_TIM9_STOP <i> TIM9 counter stopped when core is halted
|
||||
// <o.1> DBG_TIM8_STOP <i> TIM8 counter stopped when core is halted
|
||||
// <o.0> DBG_TIM1_STOP <i> TIM1 counter stopped when core is halted
|
||||
// </h>
|
||||
DbgMCU_APB2_Fz = 0x00000000;
|
||||
|
||||
// <h> TPIU Pin Routing (TRACECLK fixed on Pin PE2)
|
||||
// <i> TRACECLK: Pin PE2
|
||||
// <o1> TRACED0
|
||||
// <i> ETM Trace Data 0
|
||||
// <0x00040003=> Pin PE3
|
||||
// <0x00020001=> Pin PC1
|
||||
// <0x0006000D=> Pin PG13
|
||||
// <o2> TRACED1
|
||||
// <i> ETM Trace Data 1
|
||||
// <0x00040004=> Pin PE4
|
||||
// <0x00020008=> Pin PC8
|
||||
// <0x0006000E=> Pin PG14
|
||||
// <o3> TRACED2
|
||||
// <i> ETM Trace Data 2
|
||||
// <0x00040005=> Pin PE5
|
||||
// <0x00030002=> Pin PD2
|
||||
// <o4> TRACED3
|
||||
// <i> ETM Trace Data 3
|
||||
// <0x00040006=> Pin PE6
|
||||
// <0x0002000C=> Pin PC12
|
||||
// </h>
|
||||
TraceClk_Pin = 0x00040002;
|
||||
TraceD0_Pin = 0x00040003;
|
||||
TraceD1_Pin = 0x00040004;
|
||||
TraceD2_Pin = 0x00040005;
|
||||
TraceD3_Pin = 0x00040006;
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
9
MDK-ARM/EventRecorderStub.scvd
Normal file
9
MDK-ARM/EventRecorderStub.scvd
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<component_viewer schemaVersion="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd">
|
||||
|
||||
<component name="EventRecorderStub" version="1.0.0"/> <!--name and version of the component-->
|
||||
<events>
|
||||
</events>
|
||||
|
||||
</component_viewer>
|
||||
3698
MDK-ARM/For_stm32.uvguix.User
Normal file
3698
MDK-ARM/For_stm32.uvguix.User
Normal file
File diff suppressed because one or more lines are too long
3700
MDK-ARM/For_stm32.uvguix.Viktor
Normal file
3700
MDK-ARM/For_stm32.uvguix.Viktor
Normal file
File diff suppressed because one or more lines are too long
3583
MDK-ARM/For_stm32.uvguix.é¿¬Γ«α
Normal file
3583
MDK-ARM/For_stm32.uvguix.é¿¬Γ«α
Normal file
File diff suppressed because one or more lines are too long
822
MDK-ARM/For_stm32.uvoptx
Normal file
822
MDK-ARM/For_stm32.uvoptx
Normal file
@ -0,0 +1,822 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_optx.xsd">
|
||||
|
||||
<SchemaVersion>1.0</SchemaVersion>
|
||||
|
||||
<Header>### uVision Project, (C) Keil Software</Header>
|
||||
|
||||
<Extensions>
|
||||
<cExt>*.c</cExt>
|
||||
<aExt>*.s*; *.src; *.a*</aExt>
|
||||
<oExt>*.obj; *.o</oExt>
|
||||
<lExt>*.lib</lExt>
|
||||
<tExt>*.txt; *.h; *.inc; *.md</tExt>
|
||||
<pExt>*.plm</pExt>
|
||||
<CppX>*.cpp</CppX>
|
||||
<nMigrate>0</nMigrate>
|
||||
</Extensions>
|
||||
|
||||
<DaveTm>
|
||||
<dwLowDateTime>0</dwLowDateTime>
|
||||
<dwHighDateTime>0</dwHighDateTime>
|
||||
</DaveTm>
|
||||
|
||||
<Target>
|
||||
<TargetName>For_stm32</TargetName>
|
||||
<ToolsetNumber>0x4</ToolsetNumber>
|
||||
<ToolsetName>ARM-ADS</ToolsetName>
|
||||
<TargetOption>
|
||||
<CLKADS>25000000</CLKADS>
|
||||
<OPTTT>
|
||||
<gFlags>1</gFlags>
|
||||
<BeepAtEnd>1</BeepAtEnd>
|
||||
<RunSim>0</RunSim>
|
||||
<RunTarget>1</RunTarget>
|
||||
<RunAbUc>0</RunAbUc>
|
||||
</OPTTT>
|
||||
<OPTHX>
|
||||
<HexSelection>1</HexSelection>
|
||||
<FlashByte>65535</FlashByte>
|
||||
<HexRangeLowAddress>0</HexRangeLowAddress>
|
||||
<HexRangeHighAddress>0</HexRangeHighAddress>
|
||||
<HexOffset>0</HexOffset>
|
||||
</OPTHX>
|
||||
<OPTLEX>
|
||||
<PageWidth>79</PageWidth>
|
||||
<PageLength>66</PageLength>
|
||||
<TabStop>8</TabStop>
|
||||
<ListingPath></ListingPath>
|
||||
</OPTLEX>
|
||||
<ListingPage>
|
||||
<CreateCListing>1</CreateCListing>
|
||||
<CreateAListing>1</CreateAListing>
|
||||
<CreateLListing>1</CreateLListing>
|
||||
<CreateIListing>0</CreateIListing>
|
||||
<AsmCond>1</AsmCond>
|
||||
<AsmSymb>1</AsmSymb>
|
||||
<AsmXref>0</AsmXref>
|
||||
<CCond>1</CCond>
|
||||
<CCode>0</CCode>
|
||||
<CListInc>0</CListInc>
|
||||
<CSymb>0</CSymb>
|
||||
<LinkerCodeListing>0</LinkerCodeListing>
|
||||
</ListingPage>
|
||||
<OPTXL>
|
||||
<LMap>1</LMap>
|
||||
<LComments>1</LComments>
|
||||
<LGenerateSymbols>1</LGenerateSymbols>
|
||||
<LLibSym>1</LLibSym>
|
||||
<LLines>1</LLines>
|
||||
<LLocSym>1</LLocSym>
|
||||
<LPubSym>1</LPubSym>
|
||||
<LXref>0</LXref>
|
||||
<LExpSel>0</LExpSel>
|
||||
</OPTXL>
|
||||
<OPTFL>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<IsCurrentTarget>1</IsCurrentTarget>
|
||||
</OPTFL>
|
||||
<CpuCode>18</CpuCode>
|
||||
<DebugOpt>
|
||||
<uSim>0</uSim>
|
||||
<uTrg>1</uTrg>
|
||||
<sLdApp>1</sLdApp>
|
||||
<sGomain>1</sGomain>
|
||||
<sRbreak>1</sRbreak>
|
||||
<sRwatch>1</sRwatch>
|
||||
<sRmem>1</sRmem>
|
||||
<sRfunc>1</sRfunc>
|
||||
<sRbox>1</sRbox>
|
||||
<tLdApp>1</tLdApp>
|
||||
<tGomain>1</tGomain>
|
||||
<tRbreak>1</tRbreak>
|
||||
<tRwatch>1</tRwatch>
|
||||
<tRmem>1</tRmem>
|
||||
<tRfunc>1</tRfunc>
|
||||
<tRbox>1</tRbox>
|
||||
<tRtrace>1</tRtrace>
|
||||
<sRSysVw>1</sRSysVw>
|
||||
<tRSysVw>1</tRSysVw>
|
||||
<sRunDeb>0</sRunDeb>
|
||||
<sLrtime>0</sLrtime>
|
||||
<bEvRecOn>1</bEvRecOn>
|
||||
<bSchkAxf>0</bSchkAxf>
|
||||
<bTchkAxf>0</bTchkAxf>
|
||||
<nTsel>6</nTsel>
|
||||
<sDll></sDll>
|
||||
<sDllPa></sDllPa>
|
||||
<sDlgDll></sDlgDll>
|
||||
<sDlgPa></sDlgPa>
|
||||
<sIfile></sIfile>
|
||||
<tDll></tDll>
|
||||
<tDllPa></tDllPa>
|
||||
<tDlgDll></tDlgDll>
|
||||
<tDlgPa></tDlgPa>
|
||||
<tIfile></tIfile>
|
||||
<pMon>STLink\ST-LINKIII-KEIL_SWO.dll</pMon>
|
||||
</DebugOpt>
|
||||
<TargetDriverDllRegistry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>ARMRTXEVENTFLAGS</Key>
|
||||
<Name>-L70 -Z18 -C0 -M0 -T1</Name>
|
||||
</SetRegEntry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>DLGTARM</Key>
|
||||
<Name>(1010=-1,-1,-1,-1,0)(6017=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(6016=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)</Name>
|
||||
</SetRegEntry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>ARMDBGFLAGS</Key>
|
||||
<Name></Name>
|
||||
</SetRegEntry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>DLGUARM</Key>
|
||||
<Name>(105=-1,-1,-1,-1,0)</Name>
|
||||
</SetRegEntry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>UL2CM3</Key>
|
||||
<Name>UL2CM3(-S0 -C0 -P0 -FD20020000 -FC1000 -FN2 -FF0STM32F7x_2048 -FS08000000 -FL0200000 -FF1STM32F7xTCM_2048 -FS1200000 -FL1200000 -FP0($$Device:STM32F767ZITx$CMSIS\Flash\STM32F7x_2048.FLM) -FP1($$Device:STM32F767ZITx$CMSIS\Flash\STM32F7xTCM_2048.FLM))</Name>
|
||||
</SetRegEntry>
|
||||
<SetRegEntry>
|
||||
<Number>0</Number>
|
||||
<Key>ST-LINKIII-KEIL_SWO</Key>
|
||||
<Name>-U33FF6A064246313349321057 -O2254 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(5BA02477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8000 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN2 -FF0STM32F7x_2048.FLM -FS08000000 -FL0200000 -FP0($$Device:STM32F767ZITx$CMSIS\Flash\STM32F7x_2048.FLM) -FF1STM32F7xTCM_2048.FLM -FS1200000 -FL1200000 -FP1($$Device:STM32F767ZITx$CMSIS\Flash\STM32F7xTCM_2048.FLM)</Name>
|
||||
</SetRegEntry>
|
||||
</TargetDriverDllRegistry>
|
||||
<Breakpoint>
|
||||
<Bp>
|
||||
<Number>0</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>1437</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>134221116</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>1</BreakIfRCount>
|
||||
<Filename>../Src/main.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression>\\For_stm32\../Src/main.c\1437</Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>1</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>1446</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>0</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>0</BreakIfRCount>
|
||||
<Filename>../Src/main.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression></Expression>
|
||||
</Bp>
|
||||
</Breakpoint>
|
||||
<WatchWindow1>
|
||||
<Ww>
|
||||
<count>0</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>COMMAND</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>1</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>LD1_curr_setup</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>2</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>LD1_param</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>3</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>LD2_curr_setup</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>4</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>LD2_param</ItemText>
|
||||
</Ww>
|
||||
</WatchWindow1>
|
||||
<Tracepoint>
|
||||
<THDelay>0</THDelay>
|
||||
</Tracepoint>
|
||||
<DebugFlag>
|
||||
<trace>0</trace>
|
||||
<periodic>1</periodic>
|
||||
<aLwin>1</aLwin>
|
||||
<aCover>0</aCover>
|
||||
<aSer1>0</aSer1>
|
||||
<aSer2>0</aSer2>
|
||||
<aPa>0</aPa>
|
||||
<viewmode>1</viewmode>
|
||||
<vrSel>0</vrSel>
|
||||
<aSym>0</aSym>
|
||||
<aTbox>0</aTbox>
|
||||
<AscS1>0</AscS1>
|
||||
<AscS2>0</AscS2>
|
||||
<AscS3>0</AscS3>
|
||||
<aSer3>0</aSer3>
|
||||
<eProf>0</eProf>
|
||||
<aLa>0</aLa>
|
||||
<aPa1>0</aPa1>
|
||||
<AscS4>0</AscS4>
|
||||
<aSer4>0</aSer4>
|
||||
<StkLoc>1</StkLoc>
|
||||
<TrcWin>0</TrcWin>
|
||||
<newCpu>0</newCpu>
|
||||
<uProt>0</uProt>
|
||||
</DebugFlag>
|
||||
<LintExecutable></LintExecutable>
|
||||
<LintConfigFile></LintConfigFile>
|
||||
<bLintAuto>0</bLintAuto>
|
||||
<bAutoGenD>0</bAutoGenD>
|
||||
<LntExFlags>0</LntExFlags>
|
||||
<pMisraName></pMisraName>
|
||||
<pszMrule></pszMrule>
|
||||
<pSingCmds></pSingCmds>
|
||||
<pMultCmds></pMultCmds>
|
||||
<pMisraNamep></pMisraNamep>
|
||||
<pszMrulep></pszMrulep>
|
||||
<pSingCmdsp></pSingCmdsp>
|
||||
<pMultCmdsp></pMultCmdsp>
|
||||
<SystemViewers>
|
||||
<Entry>
|
||||
<Name>System Viewer\USART1</Name>
|
||||
<WinId>35905</WinId>
|
||||
</Entry>
|
||||
</SystemViewers>
|
||||
<DebugDescription>
|
||||
<Enable>1</Enable>
|
||||
<EnableFlashSeq>0</EnableFlashSeq>
|
||||
<EnableLog>0</EnableLog>
|
||||
<Protocol>2</Protocol>
|
||||
<DbgClock>10000000</DbgClock>
|
||||
</DebugDescription>
|
||||
</TargetOption>
|
||||
</Target>
|
||||
|
||||
<Group>
|
||||
<GroupName>Application/MDK-ARM</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>1</GroupNumber>
|
||||
<FileNumber>1</FileNumber>
|
||||
<FileType>2</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>startup_stm32f767xx.s</PathWithFileName>
|
||||
<FilenameWithoutPath>startup_stm32f767xx.s</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>Application/User</GroupName>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>2</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\Src\File_Handling.c</PathWithFileName>
|
||||
<FilenameWithoutPath>File_Handling.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>3</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Src/main.c</PathWithFileName>
|
||||
<FilenameWithoutPath>main.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>4</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Src/bsp_driver_sd.c</PathWithFileName>
|
||||
<FilenameWithoutPath>bsp_driver_sd.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>5</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Src/sd_diskio.c</PathWithFileName>
|
||||
<FilenameWithoutPath>sd_diskio.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>6</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Src/fatfs.c</PathWithFileName>
|
||||
<FilenameWithoutPath>fatfs.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>7</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Src/fatfs_platform.c</PathWithFileName>
|
||||
<FilenameWithoutPath>fatfs_platform.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>8</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Src/stm32f7xx_it.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_it.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>9</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Src/stm32f7xx_hal_msp.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_msp.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>Drivers/STM32F7xx_HAL_Driver</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>10</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_adc.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>11</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc_ex.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_adc_ex.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>12</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_rcc.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>13</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc_ex.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_rcc_ex.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>14</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_flash.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>15</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash_ex.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_flash_ex.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>16</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_gpio.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_gpio.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>17</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_dma.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>18</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma_ex.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_dma_ex.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>19</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_pwr.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>20</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr_ex.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_pwr_ex.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>21</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_cortex.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_cortex.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>22</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>23</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_i2c.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>24</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c_ex.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_i2c_ex.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>25</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_exti.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_exti.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>26</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_rcc.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_ll_rcc.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>27</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_utils.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_ll_utils.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>28</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_exti.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_ll_exti.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>29</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_gpio.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_ll_gpio.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>30</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_dma.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_ll_dma.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>31</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_sdmmc.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_ll_sdmmc.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>32</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_sd.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>33</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_spi.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_ll_spi.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>34</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_tim.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>35</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim_ex.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_hal_tim_ex.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>36</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_tim.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_ll_tim.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>3</GroupNumber>
|
||||
<FileNumber>37</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_usart.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stm32f7xx_ll_usart.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>Drivers/CMSIS</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>4</GroupNumber>
|
||||
<FileNumber>38</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Src/system_stm32f7xx.c</PathWithFileName>
|
||||
<FilenameWithoutPath>system_stm32f7xx.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>Middlewares/FatFs</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>39</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Middlewares/Third_Party/FatFs/src/diskio.c</PathWithFileName>
|
||||
<FilenameWithoutPath>diskio.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>40</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Middlewares/Third_Party/FatFs/src/ff.c</PathWithFileName>
|
||||
<FilenameWithoutPath>ff.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>41</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Middlewares/Third_Party/FatFs/src/ff_gen_drv.c</PathWithFileName>
|
||||
<FilenameWithoutPath>ff_gen_drv.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>42</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>../Middlewares/Third_Party/FatFs/src/option/syscall.c</PathWithFileName>
|
||||
<FilenameWithoutPath>syscall.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>::CMSIS</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>1</RteFlg>
|
||||
</Group>
|
||||
|
||||
</ProjectOpt>
|
||||
1159
MDK-ARM/For_stm32.uvprojx
Normal file
1159
MDK-ARM/For_stm32.uvprojx
Normal file
File diff suppressed because it is too large
Load Diff
2
MDK-ARM/For_stm32/ExtDll.iex
Normal file
2
MDK-ARM/For_stm32/ExtDll.iex
Normal file
@ -0,0 +1,2 @@
|
||||
[EXTDLL]
|
||||
Count=0
|
||||
47
MDK-ARM/For_stm32/For_stm32.lnp
Normal file
47
MDK-ARM/For_stm32/For_stm32.lnp
Normal file
@ -0,0 +1,47 @@
|
||||
--cpu Cortex-M7.fp.dp
|
||||
"for_stm32\startup_stm32f767xx.o"
|
||||
"for_stm32\file_handling.o"
|
||||
"for_stm32\main.o"
|
||||
"for_stm32\bsp_driver_sd.o"
|
||||
"for_stm32\sd_diskio.o"
|
||||
"for_stm32\fatfs.o"
|
||||
"for_stm32\fatfs_platform.o"
|
||||
"for_stm32\stm32f7xx_it.o"
|
||||
"for_stm32\stm32f7xx_hal_msp.o"
|
||||
"for_stm32\stm32f7xx_hal_adc.o"
|
||||
"for_stm32\stm32f7xx_hal_adc_ex.o"
|
||||
"for_stm32\stm32f7xx_hal_rcc.o"
|
||||
"for_stm32\stm32f7xx_hal_rcc_ex.o"
|
||||
"for_stm32\stm32f7xx_hal_flash.o"
|
||||
"for_stm32\stm32f7xx_hal_flash_ex.o"
|
||||
"for_stm32\stm32f7xx_hal_gpio.o"
|
||||
"for_stm32\stm32f7xx_hal_dma.o"
|
||||
"for_stm32\stm32f7xx_hal_dma_ex.o"
|
||||
"for_stm32\stm32f7xx_hal_pwr.o"
|
||||
"for_stm32\stm32f7xx_hal_pwr_ex.o"
|
||||
"for_stm32\stm32f7xx_hal_cortex.o"
|
||||
"for_stm32\stm32f7xx_hal.o"
|
||||
"for_stm32\stm32f7xx_hal_i2c.o"
|
||||
"for_stm32\stm32f7xx_hal_i2c_ex.o"
|
||||
"for_stm32\stm32f7xx_hal_exti.o"
|
||||
"for_stm32\stm32f7xx_ll_rcc.o"
|
||||
"for_stm32\stm32f7xx_ll_utils.o"
|
||||
"for_stm32\stm32f7xx_ll_exti.o"
|
||||
"for_stm32\stm32f7xx_ll_gpio.o"
|
||||
"for_stm32\stm32f7xx_ll_dma.o"
|
||||
"for_stm32\stm32f7xx_ll_sdmmc.o"
|
||||
"for_stm32\stm32f7xx_hal_sd.o"
|
||||
"for_stm32\stm32f7xx_ll_spi.o"
|
||||
"for_stm32\stm32f7xx_hal_tim.o"
|
||||
"for_stm32\stm32f7xx_hal_tim_ex.o"
|
||||
"for_stm32\stm32f7xx_ll_tim.o"
|
||||
"for_stm32\stm32f7xx_ll_usart.o"
|
||||
"for_stm32\system_stm32f7xx.o"
|
||||
"for_stm32\diskio.o"
|
||||
"for_stm32\ff.o"
|
||||
"for_stm32\ff_gen_drv.o"
|
||||
"for_stm32\syscall.o"
|
||||
--strict --scatter "For_stm32\For_stm32.sct"
|
||||
--summary_stderr --info summarysizes --map --load_addr_map_info --xref --callgraph --symbols
|
||||
--info sizes --info totals --info unused --info veneers
|
||||
--list "For_stm32.map" -o For_stm32\For_stm32.axf
|
||||
16
MDK-ARM/For_stm32/For_stm32.sct
Normal file
16
MDK-ARM/For_stm32/For_stm32.sct
Normal file
@ -0,0 +1,16 @@
|
||||
; *************************************************************
|
||||
; *** Scatter-Loading Description File generated by uVision ***
|
||||
; *************************************************************
|
||||
|
||||
LR_IROM1 0x08000000 0x00200000 { ; load region size_region
|
||||
ER_IROM1 0x08000000 0x00200000 { ; load address = execution address
|
||||
*.o (RESET, +First)
|
||||
*(InRoot$$Sections)
|
||||
.ANY (+RO)
|
||||
.ANY (+XO)
|
||||
}
|
||||
RW_IRAM1 0x20000000 0x00080000 { ; RW data
|
||||
.ANY (+RW +ZI)
|
||||
}
|
||||
}
|
||||
|
||||
15
MDK-ARM/For_stm32/For_stm32_sct.Bak
Normal file
15
MDK-ARM/For_stm32/For_stm32_sct.Bak
Normal file
@ -0,0 +1,15 @@
|
||||
; *************************************************************
|
||||
; *** Scatter-Loading Description File generated by uVision ***
|
||||
; *************************************************************
|
||||
|
||||
LR_IROM1 0x08000000 0x00200000 { ; load region size_region
|
||||
ER_IROM1 0x08000000 0x00200000 { ; load address = execution address
|
||||
*.o (RESET, +First)
|
||||
*(InRoot$$Sections)
|
||||
.ANY (+RO)
|
||||
}
|
||||
RW_IRAM1 0x20000000 0x00080000 { ; RW data
|
||||
.ANY (+RW +ZI)
|
||||
}
|
||||
}
|
||||
|
||||
BIN
MDK-ARM/For_stm32/bsp_driver_sd.crf
Normal file
BIN
MDK-ARM/For_stm32/bsp_driver_sd.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/diskio.crf
Normal file
BIN
MDK-ARM/For_stm32/diskio.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/fatfs.crf
Normal file
BIN
MDK-ARM/For_stm32/fatfs.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/fatfs_platform.crf
Normal file
BIN
MDK-ARM/For_stm32/fatfs_platform.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/ff.crf
Normal file
BIN
MDK-ARM/For_stm32/ff.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/ff_gen_drv.crf
Normal file
BIN
MDK-ARM/For_stm32/ff_gen_drv.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/file_handling.crf
Normal file
BIN
MDK-ARM/For_stm32/file_handling.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/main.crf
Normal file
BIN
MDK-ARM/For_stm32/main.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/sd_diskio.crf
Normal file
BIN
MDK-ARM/For_stm32/sd_diskio.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_adc.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_adc.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_adc_ex.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_adc_ex.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_cortex.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_cortex.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_dma.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_dma.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_dma_ex.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_dma_ex.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_exti.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_exti.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_flash.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_flash.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_flash_ex.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_flash_ex.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_gpio.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_gpio.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_i2c.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_i2c.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_i2c_ex.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_i2c_ex.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_msp.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_msp.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_pwr.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_pwr.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_pwr_ex.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_pwr_ex.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_rcc.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_rcc.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_rcc_ex.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_rcc_ex.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_sd.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_sd.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_spi.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_spi.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_spi_ex.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_spi_ex.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_tim.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_tim.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_tim_ex.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_tim_ex.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_uart.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_uart.crf
Normal file
Binary file not shown.
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_uart_ex.crf
Normal file
BIN
MDK-ARM/For_stm32/stm32f7xx_hal_uart_ex.crf
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user