-
Notifications
You must be signed in to change notification settings - Fork 0
Adds Engine Synchronization #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e5b4252
3fa73d7
3f236e8
100acec
1c9eef4
26885cb
75e708f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| name: Unit Tests | ||
|
|
||
| on: | ||
| push: | ||
| branches: [ main ] | ||
| pull_request: | ||
| branches: [ main ] | ||
|
|
||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| submodules: recursive | ||
|
|
||
| - name: Install dependencies | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y \ | ||
| build-essential \ | ||
| cmake \ | ||
| gcc \ | ||
| g++ \ | ||
| ninja-build | ||
|
|
||
| - name: Run tests | ||
| run: | | ||
| chmod +x run_tests.sh | ||
| ./run_tests.sh | ||
|
|
||
| - name: Upload test results | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: test-results | ||
| path: test/build/Testing/ | ||
| if-no-files-found: ignore |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| #ifndef __SAMPLING_H | ||
| #define __SAMPLING_H | ||
| #include <stdbool.h> | ||
| #include <stdint.h> | ||
|
|
||
| /** | ||
| * @brief Callback for when a cam tooth is detected. | ||
| * @param None | ||
| * @retval None | ||
| */ | ||
| void on_cam_tooth(); | ||
|
|
||
| /** | ||
| * @brief Callback for when a crank tooth is detected. | ||
| * @param None | ||
| * @retval None | ||
| */ | ||
| void on_crank_tooth(); | ||
|
|
||
| /** | ||
| * @brief Get the current fraction of tooth passed since last crank tooth. | ||
| * @param None | ||
| * @retval Fraction of tooth passed (0.0 to 1.0) | ||
| */ | ||
| float get_current_fraction_of_tooth(); | ||
|
|
||
| /** | ||
| * @brief Get the current engine angle in degrees. | ||
| * @param None | ||
| * @retval Current engine angle in degrees (0.0 to 720.0) | ||
| */ | ||
| float get_current_engine_angle(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: unused |
||
|
|
||
|
|
||
| /** | ||
| * @brief Handles synchronization detection with cam and crank signals. | ||
| * Specifically for the Honda CBR600CC engine with 12 equally-spaced | ||
| * crank teeth and 3 cam teeth, with one offset 30deg. | ||
| * | ||
| * Updates synced bool in SyncState struct. | ||
| * | ||
| * @param None. | ||
| * @retval None. | ||
| */ | ||
| void detectSync(void); | ||
|
|
||
| // General Engine Synchronization State. | ||
| struct SyncState { | ||
| // Whether we have locked synchronization or not. | ||
| bool synced; | ||
|
|
||
| // Crank index. | ||
| volatile uint8_t crank_index = 0; | ||
|
|
||
| // Monotonic crank counter. | ||
| volatile uint64_t crank_counter = 0; | ||
|
|
||
| // Monotonic cam crank counter. | ||
| volatile uint64_t cam_crank_counter = 0; | ||
|
|
||
| // Monotonic cam crank counter for last cam seen. | ||
| volatile uint64_t last_cam_crank_counter = 0; | ||
|
|
||
| // Last time in micros when we saw a crank tooth. | ||
| volatile uint32_t last_crank_time_us = 0; | ||
|
|
||
| // Last time in micros when we saw a cam tooth. | ||
| volatile uint32_t last_cam_time_us = 0; | ||
|
|
||
| // Instantaneous period between crank teeth (in microseconds). | ||
| volatile double tooth_period_us = 0.0; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. using a 64 bit value on a 32 bit processor in ISR is probably a bad idea, as it's not atomic and can tear mid write There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should probably just avoid most floating point arithmetic in ISR context, as that could be messy at high RPMs |
||
|
|
||
| // Engine phase (0 = 0-360, 1 = 360-720). | ||
| bool engine_phase; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be marked volatile, as we use it in both ISR and task |
||
|
|
||
| // Gets the delta in crank teeth between the last two cam teeth. | ||
| inline uint8_t get_cam_delta() { | ||
| return cam_crank_counter - last_cam_crank_counter; | ||
| }; | ||
|
Comment on lines
+77
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just as a safety thing, if this underflows we would see garbage data that we would not thing is garbage |
||
| }; | ||
|
|
||
| extern struct SyncState syncState; | ||
|
|
||
| #endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| #include <cmsis_os2.h> | ||
| #include <stdint.h> | ||
|
|
||
| #include "engine.h" | ||
| #include "sampling.hpp" | ||
| #include "ulog.h" | ||
| #include "us_timer.h" | ||
|
|
||
| uint32_t last_time = 0; | ||
| uint32_t time = 0; | ||
|
|
||
| void criticalEngineTask(void *argument) { | ||
| (void)argument; // Unused parameter | ||
|
|
||
| ULOG_INFO("Engine task started - waiting for sync..."); | ||
|
|
||
| for (;;) { | ||
| // Wait for sync to be acquired by cam tooth interrupts | ||
| if (!syncState.synced) { | ||
| // Sleep briefly to avoid busy-waiting | ||
| osDelay(1); | ||
| continue; | ||
| } | ||
|
|
||
| // We're synced - perform engine control operations | ||
| float current_angle = get_current_engine_angle(); | ||
|
|
||
| // TODO: Schedule fuel injection events | ||
| // TODO: Schedule ignition events | ||
|
|
||
| // ULOG_INFO("EngAngle: %.2f", current_angle); | ||
|
|
||
| if (!syncState.synced) { | ||
| ULOG_WARNING("Lost sync! Re-acquiring..."); | ||
| continue; | ||
| } | ||
|
|
||
| // Sleep briefly - actual timing is interrupt-driven | ||
| osDelay(1); | ||
|
Comment on lines
+17
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be wrong, but I think this is a TOCTOU issue with syncState.synced |
||
| } | ||
| } | ||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: unused