Initial sync implementation
Implemented system sync with crank and cam state and simple error handling
This commit is contained in:
@@ -3,21 +3,27 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <ring_buffer.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_CAM_MISS 2
|
||||
|
||||
typedef enum { SYNC_OK = 0, SYNC_PENDING = 1, SYNC_NOT_OK = 2 } sync_state_t;
|
||||
|
||||
typedef enum {
|
||||
SYNC_OK = 0,
|
||||
SYNC_PENDING = 1,
|
||||
SYNC_NOT_OK = 2
|
||||
} sync_state;
|
||||
typedef enum {
|
||||
CYCLE_EXHAUST = 0,
|
||||
CYCLE_INTAKE = 1,
|
||||
CYCLE_COMPRESSION = 2,
|
||||
CYCLE_COMBUSTION = 3,
|
||||
CYCLE_COMBUSTION = 0,
|
||||
CYCLE_EXHAUST = 1,
|
||||
CYCLE_INTAKE = 2,
|
||||
CYCLE_COMPRESSION = 3,
|
||||
CYCLE_UNKNOWN = 4
|
||||
} crank_state;
|
||||
} crank_state_t;
|
||||
|
||||
typedef enum { CAM_IDLE = 0, CAM_TRIGD = 1 } cam_state_t;
|
||||
|
||||
typedef struct {
|
||||
crank_state cycle;
|
||||
sync_state sync;
|
||||
crank_state_t crank_state;
|
||||
cam_state_t cam_state;
|
||||
uint8_t cam_miss_ctr;
|
||||
sync_state_t sync_state;
|
||||
ring_buffer_t crank_RB;
|
||||
ring_buffer_t cam_RB;
|
||||
} global_state_t;
|
||||
|
||||
13
STM32/CM7/Core/Inc/macros.h
Normal file
13
STM32/CM7/Core/Inc/macros.h
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
|
||||
// Copyright (C) 2026 Pierre Barbier <pierrebarbier741@gmail.com>
|
||||
// Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "SEGGER_RTT.h"
|
||||
#define DEBUG_LOG(fmt, ...) SEGGER_RTT_printf(0, fmt "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_LOG(fmt, ...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
@@ -160,7 +160,10 @@ int main(void)
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
state_g.sync = SYNC_NOT_OK;
|
||||
state_g.sync_state = SYNC_NOT_OK;
|
||||
state_g.crank_state = CYCLE_UNKNOWN;
|
||||
state_g.cam_state = CAM_IDLE;
|
||||
state_g.cam_miss_ctr = 0;
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
@@ -359,7 +362,7 @@ static void MX_TIM2_Init(void)
|
||||
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
|
||||
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
|
||||
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
|
||||
sConfigIC.ICFilter = 0;
|
||||
sConfigIC.ICFilter = 10;
|
||||
if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
|
||||
@@ -4,22 +4,37 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "cmsis_os2.h"
|
||||
#include "macros.h"
|
||||
#include "main.h"
|
||||
#include "ring_buffer.h"
|
||||
#include "tasks.h"
|
||||
#ifdef DEBUG
|
||||
#include "SEGGER_RTT.h"
|
||||
#endif
|
||||
|
||||
void camHandler(void *argument) {
|
||||
for (;;) {
|
||||
osThreadFlagsWait(0x01, osFlagsWaitAny, osWaitForever);
|
||||
#ifdef DEBUG
|
||||
SEGGER_RTT_printf(0, "Cam pulse detected at: %lu\n\r",
|
||||
|
||||
DEBUG_LOG("Cam pulse detected at: %lu\n\r",
|
||||
ringBufferRead(&state_g.cam_RB, 0));
|
||||
#endif /* ifdef DEBUG */
|
||||
if (state_g.sync == SYNC_OK) {
|
||||
// TODO complete algorithm for scheduling spark
|
||||
|
||||
// FILTERS
|
||||
|
||||
state_g.cam_state = CAM_TRIGD;
|
||||
state_g.cam_miss_ctr = 0;
|
||||
switch (state_g.sync_state) {
|
||||
case SYNC_NOT_OK: {
|
||||
state_g.sync_state = SYNC_PENDING;
|
||||
DEBUG_LOG("Sync state updated to pending\n\r");
|
||||
break;
|
||||
}
|
||||
case SYNC_PENDING: {
|
||||
if (state_g.crank_state == CYCLE_COMPRESSION) {
|
||||
state_g.sync_state = SYNC_OK;
|
||||
DEBUG_LOG("Sync state updated to OK\n\r");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,22 +4,63 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "cmsis_os2.h"
|
||||
#include "macros.h"
|
||||
#include "main.h"
|
||||
#include "ring_buffer.h"
|
||||
#include "tasks.h"
|
||||
#ifdef DEBUG
|
||||
#include "SEGGER_RTT.h"
|
||||
#endif
|
||||
|
||||
void crankHandler(void *argument) {
|
||||
for (;;) {
|
||||
osThreadFlagsWait(0x01, osFlagsWaitAny, osWaitForever);
|
||||
#ifdef DEBUG
|
||||
SEGGER_RTT_printf(0, "Crank pulse detected at: %lu\n\r",
|
||||
DEBUG_LOG("Crank pulse detected at: %lu\n\r",
|
||||
ringBufferRead(&state_g.crank_RB, 0));
|
||||
#endif /* ifdef DEBUG */
|
||||
if (state_g.sync == SYNC_OK) {
|
||||
// TODO complete algorithm for scheduling spark
|
||||
// FILTER
|
||||
|
||||
// INCREMENT SWITCH
|
||||
switch (state_g.crank_state) {
|
||||
case CYCLE_COMPRESSION: {
|
||||
if (state_g.cam_state != CAM_TRIGD) {
|
||||
DEBUG_LOG("Cam miss detected, sync dynamite incoming\n\r");
|
||||
state_g.cam_miss_ctr++;
|
||||
if (state_g.cam_miss_ctr > MAX_CAM_MISS) {
|
||||
state_g.sync_state = SYNC_NOT_OK;
|
||||
state_g.crank_state = CYCLE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
state_g.crank_state = CYCLE_COMBUSTION;
|
||||
DEBUG_LOG("Crank state incremented\n\r");
|
||||
state_g.cam_state = CAM_IDLE;
|
||||
break;
|
||||
}
|
||||
case CYCLE_COMBUSTION:
|
||||
case CYCLE_EXHAUST:
|
||||
case CYCLE_INTAKE: {
|
||||
if (state_g.cam_state == CAM_TRIGD) {
|
||||
state_g.sync_state = SYNC_NOT_OK;
|
||||
state_g.crank_state = CYCLE_UNKNOWN;
|
||||
state_g.cam_state = CAM_IDLE;
|
||||
break;
|
||||
}
|
||||
state_g.crank_state++;
|
||||
DEBUG_LOG("Crank state incremented\n\r");
|
||||
break;
|
||||
}
|
||||
case CYCLE_UNKNOWN: {
|
||||
if (state_g.sync_state == SYNC_PENDING &&
|
||||
state_g.cam_state == CAM_TRIGD) {
|
||||
state_g.crank_state = CYCLE_COMBUSTION;
|
||||
state_g.cam_state = CAM_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// SPARK SCHEDULE
|
||||
if (state_g.crank_state == CYCLE_COMPRESSION &&
|
||||
state_g.sync_state == SYNC_OK) {
|
||||
DEBUG_LOG("Spark schedule reached, congrats\n\r");
|
||||
// TODO: schedule spark
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,8 +249,10 @@ SYS.userName=SYS_M7
|
||||
TIM2.Channel-Input_Capture1_from_TI1=TIM_CHANNEL_1
|
||||
TIM2.Channel-Input_Capture2_from_TI2=TIM_CHANNEL_2
|
||||
TIM2.ClockDivision=TIM_CLOCKDIVISION_DIV4
|
||||
TIM2.ICFilter_CH1=10
|
||||
TIM2.ICFilter_CH2=10
|
||||
TIM2.ICPolarity_CH1=TIM_INPUTCHANNELPOLARITY_FALLING
|
||||
TIM2.IPParameters=ClockDivision,Prescaler,Channel-Input_Capture1_from_TI1,ICPolarity_CH1,Channel-Input_Capture2_from_TI2
|
||||
TIM2.IPParameters=ClockDivision,Prescaler,Channel-Input_Capture1_from_TI1,ICPolarity_CH1,Channel-Input_Capture2_from_TI2,ICFilter_CH2,ICFilter_CH1
|
||||
TIM2.Prescaler=0
|
||||
VP_FREERTOS_M7_VS_CMSIS_V2.Mode=CMSIS_V2
|
||||
VP_FREERTOS_M7_VS_CMSIS_V2.Signal=FREERTOS_M7_VS_CMSIS_V2
|
||||
|
||||
Reference in New Issue
Block a user