Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 29 additions & 166 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,171 +86,34 @@ Module.symvers
Mkfile.old
dkms.conf

.idea
/cmake-build-debug/
# IDE
.idea/
/.settings/
*.launch

# CMake build artifacts (firmware and emulator)
/build/
/cmake-build-*/
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
Makefile
/.cmake/

# Firmware build outputs
/Debug/
/rotary-controller-f4.launch
/Release/Core/Src/freertos.cyclo
/Release/Core/Src/gpio.cyclo
/Release/Core/Src/main.cyclo
/Release/Core/Src/Modbus.cyclo
/Release/Core/Src/Ramps.cyclo
/Release/Core/Src/Scales.cyclo
/Release/Core/Src/stm32f4xx_hal_msp.cyclo
/Release/Core/Src/stm32f4xx_hal_timebase_tim.cyclo
/Release/Core/Src/stm32f4xx_it.cyclo
/Release/Core/Src/subdir.mk
/Release/Core/Src/syscalls.cyclo
/Release/Core/Src/sysmem.cyclo
/Release/Core/Src/system_stm32f4xx.cyclo
/Release/Core/Src/tim.cyclo
/Release/Core/Src/UARTCallback.cyclo
/Release/Core/Src/usart.cyclo
/Release/Core/Startup/subdir.mk
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.cyclo
/Release/Drivers/STM32F4xx_HAL_Driver/Src/subdir.mk
/Release/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.cyclo
/Release/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/subdir.mk
/Release/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.cyclo
/Release/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/subdir.mk
/Release/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.cyclo
/Release/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/subdir.mk
/Release/Middlewares/Third_Party/FreeRTOS/Source/croutine.cyclo
/Release/Middlewares/Third_Party/FreeRTOS/Source/event_groups.cyclo
/Release/Middlewares/Third_Party/FreeRTOS/Source/list.cyclo
/Release/Middlewares/Third_Party/FreeRTOS/Source/queue.cyclo
/Release/Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.cyclo
/Release/Middlewares/Third_Party/FreeRTOS/Source/subdir.mk
/Release/Middlewares/Third_Party/FreeRTOS/Source/tasks.cyclo
/Release/Middlewares/Third_Party/FreeRTOS/Source/timers.cyclo
/Release/makefile
/Release/objects.list
/Release/objects.mk
/Release/rotary-controller-f4.list
/Release/sources.mk
/rotary-controller-f4.bin
/Makefile
/CMakeCache.txt
/cmake_install.cmake
/CMakeFiles/4.0.2/CompilerIdC/CMakeCCompilerId.c
/CMakeFiles/4.0.2/CompilerIdCXX/CMakeCXXCompilerId.cpp
/CMakeFiles/4.0.2/CMakeASMCompiler.cmake
/CMakeFiles/4.0.2/CMakeCCompiler.cmake
/CMakeFiles/4.0.2/CMakeCXXCompiler.cmake
/CMakeFiles/4.0.2/CMakeDetermineCompilerABI_C.bin
/CMakeFiles/4.0.2/CMakeDetermineCompilerABI_CXX.bin
/CMakeFiles/4.0.2/CMakeSystem.cmake
/CMakeFiles/4.0.3-dirty/CompilerIdC/CMakeCCompilerId.c
/CMakeFiles/4.0.3-dirty/CompilerIdCXX/CMakeCXXCompilerId.cpp
/CMakeFiles/4.0.3-dirty/CMakeASMCompiler.cmake
/CMakeFiles/4.0.3-dirty/CMakeCCompiler.cmake
/CMakeFiles/4.0.3-dirty/CMakeCXXCompiler.cmake
/CMakeFiles/4.0.3-dirty/CMakeDetermineCompilerABI_C.bin
/CMakeFiles/4.0.3-dirty/CMakeDetermineCompilerABI_CXX.bin
/CMakeFiles/4.0.3-dirty/CMakeSystem.cmake
/CMakeFiles/4.1.2/CompilerIdC/CMakeCCompilerId.c
/CMakeFiles/4.1.2/CompilerIdCXX/CMakeCXXCompilerId.cpp
/CMakeFiles/4.1.2/CMakeASMCompiler.cmake
/CMakeFiles/4.1.2/CMakeCCompiler.cmake
/CMakeFiles/4.1.2/CMakeCXXCompiler.cmake
/CMakeFiles/4.1.2/CMakeDetermineCompilerABI_C.bin
/CMakeFiles/4.1.2/CMakeDetermineCompilerABI_CXX.bin
/CMakeFiles/4.1.2/CMakeSystem.cmake
/CMakeFiles/4.2.1/CompilerIdC/CMakeCCompilerId.c
/CMakeFiles/4.2.1/CompilerIdCXX/CMakeCXXCompilerId.cpp
/CMakeFiles/4.2.1/CMakeASMCompiler.cmake
/CMakeFiles/4.2.1/CMakeCCompiler.cmake
/CMakeFiles/4.2.1/CMakeCXXCompiler.cmake
/CMakeFiles/4.2.1/CMakeDetermineCompilerABI_C.bin
/CMakeFiles/4.2.1/CMakeDetermineCompilerABI_CXX.bin
/CMakeFiles/4.2.1/CMakeSystem.cmake
/CMakeFiles/rotary-controller-f4.elf.dir/ASM.includecache
/CMakeFiles/rotary-controller-f4.elf.dir/build.make
/CMakeFiles/rotary-controller-f4.elf.dir/cmake_clean.cmake
/CMakeFiles/rotary-controller-f4.elf.dir/compiler_depend.make
/CMakeFiles/rotary-controller-f4.elf.dir/compiler_depend.ts
/CMakeFiles/rotary-controller-f4.elf.dir/depend.internal
/CMakeFiles/rotary-controller-f4.elf.dir/depend.make
/CMakeFiles/rotary-controller-f4.elf.dir/DependInfo.cmake
/CMakeFiles/rotary-controller-f4.elf.dir/flags.make
/CMakeFiles/rotary-controller-f4.elf.dir/link.txt
/CMakeFiles/rotary-controller-f4.elf.dir/progress.make
/CMakeFiles/clion-environment.txt
/CMakeFiles/cmake.check_cache
/CMakeFiles/CMakeConfigureLog.yaml
/CMakeFiles/CMakeDirectoryInformation.cmake
/CMakeFiles/InstallScripts.json
/CMakeFiles/Makefile.cmake
/CMakeFiles/Makefile2
/CMakeFiles/progress.marks
/CMakeFiles/TargetDirectories.txt
/cmake-build-release/.cmake/api/v1/query/cache-v2
/cmake-build-release/.cmake/api/v1/query/cmakeFiles-v1
/cmake-build-release/.cmake/api/v1/query/codemodel-v2
/cmake-build-release/.cmake/api/v1/query/toolchains-v1
/cmake-build-release/.cmake/api/v1/reply/cache-v2-75ccddff1f9462878f34.json
/cmake-build-release/.cmake/api/v1/reply/cmakeFiles-v1-efb40c770de9d5bf104a.json
/cmake-build-release/.cmake/api/v1/reply/codemodel-v2-1d0bfa3e0f2ca88c0356.json
/cmake-build-release/.cmake/api/v1/reply/directory-.-Release-f5ebdc15457944623624.json
/cmake-build-release/.cmake/api/v1/reply/index-2025-07-25T20-06-13-0400.json
/cmake-build-release/.cmake/api/v1/reply/target-rotary-controller-f4.elf-Release-23665a0d8e0985d66bdc.json
/cmake-build-release/.cmake/api/v1/reply/toolchains-v1-516567ce22d77594ccde.json
/cmake-build-release/CMakeFiles/3.31.6/CompilerIdC/CMakeCCompilerId.c
/cmake-build-release/CMakeFiles/3.31.6/CompilerIdCXX/CMakeCXXCompilerId.cpp
/cmake-build-release/CMakeFiles/3.31.6/CMakeASMCompiler.cmake
/cmake-build-release/CMakeFiles/3.31.6/CMakeCCompiler.cmake
/cmake-build-release/CMakeFiles/3.31.6/CMakeCXXCompiler.cmake
/cmake-build-release/CMakeFiles/3.31.6/CMakeDetermineCompilerABI_C.bin
/cmake-build-release/CMakeFiles/3.31.6/CMakeDetermineCompilerABI_CXX.bin
/cmake-build-release/CMakeFiles/3.31.6/CMakeSystem.cmake
/cmake-build-release/CMakeFiles/rotary-controller-f4.elf.dir/ASM.includecache
/cmake-build-release/CMakeFiles/rotary-controller-f4.elf.dir/build.make
/cmake-build-release/CMakeFiles/rotary-controller-f4.elf.dir/cmake_clean.cmake
/cmake-build-release/CMakeFiles/rotary-controller-f4.elf.dir/compiler_depend.make
/cmake-build-release/CMakeFiles/rotary-controller-f4.elf.dir/compiler_depend.ts
/cmake-build-release/CMakeFiles/rotary-controller-f4.elf.dir/depend.internal
/cmake-build-release/CMakeFiles/rotary-controller-f4.elf.dir/depend.make
/cmake-build-release/CMakeFiles/rotary-controller-f4.elf.dir/DependInfo.cmake
/cmake-build-release/CMakeFiles/rotary-controller-f4.elf.dir/flags.make
/cmake-build-release/CMakeFiles/rotary-controller-f4.elf.dir/link.txt
/cmake-build-release/CMakeFiles/rotary-controller-f4.elf.dir/progress.make
/cmake-build-release/CMakeFiles/clion-environment.txt
/cmake-build-release/CMakeFiles/clion-Release-log.txt
/cmake-build-release/CMakeFiles/cmake.check_cache
/cmake-build-release/CMakeFiles/CMakeConfigureLog.yaml
/cmake-build-release/CMakeFiles/CMakeDirectoryInformation.cmake
/cmake-build-release/CMakeFiles/Makefile.cmake
/cmake-build-release/CMakeFiles/Makefile2
/cmake-build-release/CMakeFiles/progress.marks
/cmake-build-release/CMakeFiles/TargetDirectories.txt
/cmake-build-release/cmake_install.cmake
/cmake-build-release/CMakeCache.txt
/cmake-build-release/Makefile
/cmake-build-release/rotary-controller-f4.bin
/.cmake/api/v1/query/cache-v2
/.cmake/api/v1/query/cmakeFiles-v1
/.cmake/api/v1/query/codemodel-v2
/.cmake/api/v1/query/toolchains-v1
/.cmake/api/v1/reply/cache-v2-f5e9ca3708de3f124d35.json
/.cmake/api/v1/reply/cmakeFiles-v1-281ea38263c07c7344ed.json
/.cmake/api/v1/reply/codemodel-v2-f943dd8c247e07984a15.json
/.cmake/api/v1/reply/directory-.-Release-9ad1a58d4644cf6543fa.json
/.cmake/api/v1/reply/index-2026-01-26T01-20-50-0476.json
/.cmake/api/v1/reply/target-rotary-controller-f4.elf-Release-abbd90adbbfbd406bb3c.json
/.cmake/api/v1/reply/toolchains-v1-516567ce22d77594ccde.json
/Release/
*.bin
*.cyclo
*.list
objects.list
objects.mk
sources.mk
makefile
subdir.mk

# Emulator build
/emulator/build*/

# AI
.claude/
11 changes: 6 additions & 5 deletions Core/Inc/Ramps.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ typedef struct {
} deltaPosError_t;

typedef struct {
TIM_HandleTypeDef *timerHandle;
int32_t position;
int32_t speed;
int32_t syncRatioNum, syncRatioDen;
uint16_t syncEnable;
int32_t dummy;
int32_t position; // READ-ONLY (firmware-owned): absolute encoder position, updated by ISR
int32_t speed; // READ-ONLY (firmware-owned): encoder speed (counts/s), updated by updateSpeedTask
int32_t syncRatioNum, syncRatioDen; // SW write: sync ratio numerator/denominator (output steps per input count)
uint16_t syncEnable; // SW write: 0 = sync disabled, non-zero = sync enabled for this scale
} input_t;

typedef struct {
Expand Down Expand Up @@ -106,6 +106,7 @@ typedef struct {
// STM32 Related
TIM_HandleTypeDef *synchroRefreshTimer;
UART_HandleTypeDef *modbusUart;
TIM_HandleTypeDef *scaleTimers[SCALES_COUNT];

deltaPosError_t scalesDeltaPos[SCALES_COUNT];
deltaPosError_t scalesSyncDeltaPos[SCALES_COUNT];
Expand Down
6 changes: 3 additions & 3 deletions Core/Src/Ramps.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ void RampsStart(rampsHandler_t *rampsData) {

// Initialize and start encoder timer, reset the sync flags
for (int j = 0; j < SCALES_COUNT; ++j) {
initScaleTimer(rampsData->shared.scales[j].timerHandle);
HAL_TIM_Encoder_Start(rampsData->shared.scales[j].timerHandle, TIM_CHANNEL_ALL);
initScaleTimer(rampsData->scaleTimers[j]);
HAL_TIM_Encoder_Start(rampsData->scaleTimers[j], TIM_CHANNEL_ALL);
}

// Enable debug cycle counter
Expand Down Expand Up @@ -237,7 +237,7 @@ void SynchroRefreshTimerIsr(rampsHandler_t *data) {

for (int i = 0; i < SCALES_COUNT; i++) {
data->scalesDeltaPos[i].oldPosition = data->scalesDeltaPos[i].position;
data->scalesDeltaPos[i].position = __HAL_TIM_GET_COUNTER(data->shared.scales[i].timerHandle);
data->scalesDeltaPos[i].position = __HAL_TIM_GET_COUNTER(data->scaleTimers[i]);
data->scalesDeltaPos[i].delta = (int16_t) (data->scalesDeltaPos[i].position - data->scalesDeltaPos[i].oldPosition);
shared->scales[i].position += data->scalesDeltaPos[i].delta;

Expand Down
8 changes: 4 additions & 4 deletions Core/Src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ int main(void)
// htim4 is used in encoder mode
// htim9 is used to generate the synchro motion

RampsData.shared.scales[0].timerHandle = &htim1;
RampsData.shared.scales[1].timerHandle = &htim2;
RampsData.shared.scales[2].timerHandle = &htim3;
RampsData.shared.scales[3].timerHandle = &htim4;
RampsData.scaleTimers[0] = &htim1;
RampsData.scaleTimers[1] = &htim2;
RampsData.scaleTimers[2] = &htim3;
RampsData.scaleTimers[3] = &htim4;
RampsData.synchroRefreshTimer = &htim9;
RampsData.modbusUart = &huart1;
RampsStart(&RampsData);
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This repository contains the **firmware** for a rotary controller board based on
* Modular firmware structure with FreeRTOS support
* Supports ST‑Link V2 and Raspberry Pi + OpenOCD programming
* Optimized for high-speed encoder + stepper motor control
* Includes a native lathe emulator for hardware-free testing with the Python GUI

---

Expand Down Expand Up @@ -58,6 +59,23 @@ make clean

---

## 🖥️ Lathe Emulator

A native Linux emulator is included for hardware-free firmware testing. It compiles the real firmware sources (`Ramps.c`, `Modbus.c`, `Scales.c`, `UARTCallback.c`) against a HAL/FreeRTOS shim layer and simulates lathe physics — spindle with inertia, leadscrew, carriage with half-nut engagement, and cross-slide. The emulator exposes Modbus RTU via PTY pair and TCP socket so the unmodified Python GUI can connect as if talking to real hardware.

A two-pane ANSI terminal dashboard with sparklines provides live visualization, with keyboard controls for spindle RPM, manual axis movement, half-nut engagement, and more. All parameters are configurable via TOML file.

### Emulator Build & Run

```bash
cd emulator
cmake -B build
cmake --build build
./build/lathe-emulator config/lathe.toml
```

---

## 🔧 Hardware Configuration

* `.ioc` file for use with STM32CubeMX included
Expand Down
71 changes: 71 additions & 0 deletions emulator/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
cmake_minimum_required(VERSION 3.16)
project(lathe-emulator C CXX)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Firmware source directory
set(FW_DIR ${CMAKE_SOURCE_DIR}/..)

# --- Shim headers come FIRST so they override the real HAL/FreeRTOS ---
include_directories(
${CMAKE_SOURCE_DIR}/shim
${CMAKE_SOURCE_DIR}/src
${FW_DIR}/Core/Inc
)

# Preprocessor defines to match firmware expectations
add_definitions(
-DSTM32F411xE
-DUSE_HAL_DRIVER
-DEMULATOR_BUILD
)

# Compiler warnings
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers)

# --- Firmware C sources (compiled against our shim) ---
set(FW_SOURCES
${FW_DIR}/Core/Src/Ramps.c
${FW_DIR}/Core/Src/Modbus.c
${FW_DIR}/Core/Src/Scales.c
${FW_DIR}/Core/Src/UARTCallback.c
)

# --- Shim implementations ---
set(SHIM_SOURCES
${CMAKE_SOURCE_DIR}/shim/hal_shim.c
${CMAKE_SOURCE_DIR}/shim/freertos_shim.cpp
)

# --- Emulator C++ sources ---
set(EMU_SOURCES
${CMAKE_SOURCE_DIR}/src/main.cpp
${CMAKE_SOURCE_DIR}/src/physics.cpp
${CMAKE_SOURCE_DIR}/src/transport.cpp
${CMAKE_SOURCE_DIR}/src/dashboard.cpp
${CMAKE_SOURCE_DIR}/src/config.cpp
)

add_executable(lathe-emulator
${FW_SOURCES}
${SHIM_SOURCES}
${EMU_SOURCES}
)

target_link_libraries(lathe-emulator
pthread
m
)

# Allow C++ files to include C headers
set_source_files_properties(${FW_SOURCES} PROPERTIES LANGUAGE C)
set_source_files_properties(${SHIM_SOURCES} ${EMU_SOURCES} PROPERTIES LANGUAGE CXX)

# The firmware .c files must be compiled as C, but our shim headers
# use extern "C" guards so they work from both C and C++ translation units.
# Force C compilation for firmware sources specifically.
set_source_files_properties(${FW_SOURCES} ${CMAKE_SOURCE_DIR}/shim/hal_shim.c
PROPERTIES LANGUAGE C COMPILE_FLAGS "-std=gnu11"
)
Loading