init
This commit is contained in:
+3586
File diff suppressed because it is too large
Load Diff
+233
@@ -0,0 +1,233 @@
|
||||
#ifndef MOTOR_CONTROL_H
|
||||
#define MOTOR_CONTROL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MOTOR_API_SUCCESS (0u)
|
||||
#define MOTOR_API_FAILURE (1u)
|
||||
#define MOTOR_PHYSICAL_VALUE_SCALE (100ul)
|
||||
|
||||
#define MOTOR_MODE0_DEFAULT_MAX_HALL_COUNT (480ul)
|
||||
#define MOTOR_MODE0_MAX_POSITION_MM_X100 (10200ul)
|
||||
#define MOTOR_MODE1_DEFAULT_MAX_HALL_COUNT (790ul)
|
||||
#define MOTOR_MODE1_MAX_ANGLE_DEG_X100 (8500ul)
|
||||
#define MOTOR_MODE2_DEFAULT_MAX_HALL_COUNT (1590ul)
|
||||
#define MOTOR_MODE2_MAX_ANGLE_DEG_X100 (9000ul)
|
||||
#define MOTOR_MODE3_DEFAULT_MAX_HALL_COUNT (960ul)
|
||||
#define MOTOR_MODE3_MAX_POSITION_MM_X100 (24000ul)
|
||||
|
||||
#define MOTOR_SPEED_VALUE_SCALE (100ul)
|
||||
#define MOTOR_SPEED_MIN_DUTY_PERCENT (50u)
|
||||
#define MOTOR_SPEED_MAX_DUTY_PERCENT (95u)
|
||||
#define MOTOR_SPEED_DUTY_STEP_PERCENT (5u)
|
||||
#define MOTOR_MODE0_MAX_SPEED_PPS_X100 (8600ul)
|
||||
#define MOTOR_MODE1_MAX_SPEED_PPS_X100 (6100ul)
|
||||
#define MOTOR_MODE2_MAX_SPEED_PPS_X100 (9000ul)
|
||||
#define MOTOR_MODE3_MAX_SPEED_PPS_X100 (8600ul)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MOTOR_MODE_0_LINEAR = 0,
|
||||
MOTOR_MODE_1_ANGLE,
|
||||
MOTOR_MODE_2_ANGLE,
|
||||
MOTOR_MODE_3_LINEAR_TRACK,
|
||||
MOTOR_MODE_COUNT
|
||||
} motor_mode_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MOTOR_DIRECTION_STOPPED = 0,
|
||||
MOTOR_DIRECTION_TOWARD_FAR,
|
||||
MOTOR_DIRECTION_TOWARD_NEAR
|
||||
} motor_direction_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MOTOR_EVENT_NONE = 0,
|
||||
MOTOR_EVENT_TARGET_REACHED,
|
||||
MOTOR_EVENT_NEAR_ENDPOINT,
|
||||
MOTOR_EVENT_FAR_ENDPOINT,
|
||||
MOTOR_EVENT_STALL,
|
||||
MOTOR_EVENT_TIMEOUT,
|
||||
MOTOR_EVENT_ABORTED,
|
||||
MOTOR_EVENT_DRIVER_FAULT,
|
||||
MOTOR_EVENT_CALIBRATION_FAILED
|
||||
} motor_event_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MOTOR_CALIBRATE_FIND_NEAR = 0,
|
||||
MOTOR_CALIBRATE_FIND_FAR,
|
||||
MOTOR_CALIBRATE_FIND_BOTH
|
||||
} motor_calibration_action_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
motor_mode_t mode;
|
||||
bool positionValid;
|
||||
motor_direction_t direction;
|
||||
motor_event_t lastEvent;
|
||||
uint32_t hallCount;
|
||||
uint32_t maxHallCount;
|
||||
uint32_t valueX100;
|
||||
uint32_t maxValueX100;
|
||||
uint32_t positionMmX100;
|
||||
uint32_t angleDegX100;
|
||||
uint32_t percentX100;
|
||||
} motor_position_info_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool reverseAtEndpoint;
|
||||
bool reverseAtStall;
|
||||
} motor_safety_options_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool nearEndpointFound;
|
||||
bool farEndpointFound;
|
||||
uint32_t measuredMaxHallCount;
|
||||
} motor_calibration_result_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
motor_mode_t mode;
|
||||
bool enabled;
|
||||
uint32_t durationMs;
|
||||
uint32_t travelValueX100;
|
||||
uint32_t plannedHallPulses;
|
||||
uint32_t targetPulsesPerSecondX100;
|
||||
uint32_t actualPulsesPerSecondX100;
|
||||
uint8_t initialDutyPercent;
|
||||
uint8_t currentDutyPercent;
|
||||
} motor_speed_info_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t positionHallCount;
|
||||
uint32_t maxHallCount;
|
||||
uint32_t maxSpeedPulsesPerSecondX100;
|
||||
uint32_t rawRisingEdges;
|
||||
bool positionValid;
|
||||
} motor_persistent_state_t;
|
||||
|
||||
/* Hardware initialization. SystemInit() and global IRQ enable remain owned by main. */
|
||||
uint8_t Motor_Init(void);
|
||||
/* Immediate GPIO-only safe state, also valid before Motor_Init(). */
|
||||
void Motor_ForceSafeOff(void);
|
||||
|
||||
/* The Hall timebase is a precise 2 ms hardware interrupt. */
|
||||
uint32_t Motor_GetTimeMs(void);
|
||||
void Motor_SetWatchdogServiceEnabled(bool enabled);
|
||||
|
||||
/*
|
||||
* Physical values use fixed point x100: 102.00 mm is 10200 and
|
||||
* 85.25 degrees is 8525. positionValid is false until an endpoint has
|
||||
* been found after power-up.
|
||||
*
|
||||
* Ownership contract: call all control APIs and Motor_ServiceAll from one
|
||||
* main-loop/owner context. They are not ISR-safe, thread-safe, or reentrant.
|
||||
* The four motors may still run concurrently after sequential non-blocking
|
||||
* start calls from that owner.
|
||||
*/
|
||||
uint8_t Motor_GetPositionInfo(motor_mode_t mode, motor_position_info_t *info);
|
||||
|
||||
/* Each mode has independent endpoint and stall reverse switches. */
|
||||
uint8_t Motor_SetSafetyOptions(motor_mode_t mode,
|
||||
const motor_safety_options_t *options);
|
||||
|
||||
/* Open-loop primitives used by the standardized application controller. */
|
||||
uint8_t Motor_SetFixedDutyPercent(motor_mode_t mode, uint8_t dutyPercent);
|
||||
uint8_t Motor_StartOpenLoop(motor_mode_t mode, motor_direction_t direction);
|
||||
bool Motor_IsMoving(motor_mode_t mode);
|
||||
|
||||
/*
|
||||
* Restore/store Hall-domain state. These calls are accepted only while the
|
||||
* selected motor is stopped. max speed uses Hall rising edges/s x100.
|
||||
*/
|
||||
uint8_t Motor_ApplyPersistentState(motor_mode_t mode,
|
||||
const motor_persistent_state_t *state);
|
||||
uint8_t Motor_GetPersistentState(motor_mode_t mode,
|
||||
motor_persistent_state_t *state);
|
||||
uint8_t Motor_SetMaximumSpeedPpsX100(motor_mode_t mode,
|
||||
uint32_t maxSpeedPpsX100);
|
||||
|
||||
/*
|
||||
* Pair an owner-context command with cancellation published asynchronously.
|
||||
* An acknowledge succeeds when no cancellation is pending, or when sequence
|
||||
* exactly matches it. It fails if a newer cancellation has already arrived.
|
||||
*/
|
||||
uint8_t Motor_AcknowledgeCommand(motor_mode_t mode, uint16_t sequence);
|
||||
bool Motor_IsCommandCurrent(motor_mode_t mode, uint16_t sequence);
|
||||
|
||||
/*
|
||||
* Start is non-blocking and permits all four modes to move concurrently.
|
||||
* Wait and MoveToValue return 0 only after the target is reached; endpoint,
|
||||
* stall, invalid position, invalid target, and timeout return 1.
|
||||
* Replacing a target still ahead in the same direction does not restart PWM
|
||||
* or refresh safety/timeout clocks. A direction change waits at least 100 ms
|
||||
* and until Hall has been quiet for 100 ms. Crossing a target stops PWM once;
|
||||
* residual Hall pulses remain in the global position and may leave the final
|
||||
* count beyond the target. No automatic reverse correction is performed.
|
||||
* If a safety reverse is enabled, Wait remains blocked until that reverse has
|
||||
* stopped at its next safety event or at the absolute operation timeout.
|
||||
*/
|
||||
uint8_t Motor_StartMoveToValue(motor_mode_t mode, uint32_t targetValueX100);
|
||||
uint8_t Motor_WaitForMove(motor_mode_t mode);
|
||||
uint8_t Motor_MoveToValue(motor_mode_t mode, uint32_t targetValueX100);
|
||||
uint8_t Motor_StopMode(motor_mode_t mode);
|
||||
|
||||
/*
|
||||
* Configure closed-loop speed from a planned travel amount and duration.
|
||||
* durationMs is milliseconds. travelValueX100 is mm x100 for mode 0 and
|
||||
* degrees x100 for modes 1/2, and mm x100 for mode 3. This configures speed
|
||||
* only; use an existing move API to start motion. After each real PWM start
|
||||
* the controller waits
|
||||
* 500 ms, then evaluates a 500 ms rolling Hall window every 100 ms. A speed
|
||||
* error outside +/-10 percent changes that motor's duty by one 5 percent step.
|
||||
*/
|
||||
uint8_t Motor_SetSpeedPlan(motor_mode_t mode,
|
||||
uint32_t durationMs,
|
||||
uint32_t travelValueX100);
|
||||
uint8_t Motor_DisableSpeedControl(motor_mode_t mode);
|
||||
uint8_t Motor_GetSpeedInfo(motor_mode_t mode, motor_speed_info_t *info);
|
||||
|
||||
/*
|
||||
* Calibration is blocking for the selected mode; other active modes continue.
|
||||
* A new range is committed only after validation. Failure restores the old
|
||||
* range, preserves observed motion, and invalidates absolute position because
|
||||
* physical travel cannot be rolled back. Each leg requires Hall coast
|
||||
* tracking to settle before/after travel; quiet wait is bounded to five seconds.
|
||||
*/
|
||||
uint8_t Motor_Calibrate(motor_mode_t mode,
|
||||
motor_calibration_action_t action,
|
||||
motor_calibration_result_t *result);
|
||||
|
||||
/* Call continuously from the main loop; the ISR still kills PWM immediately. */
|
||||
void Motor_ServiceAll(void);
|
||||
|
||||
/* ISR-safe immediate PWM kill; bridge Hi-Z is completed by Motor_ServiceAll. */
|
||||
void Motor_RequestAbortMaskFromIsr(uint8_t motorMask, uint16_t sequence);
|
||||
void Motor_RequestAbortAllFromIsr(uint16_t sequence);
|
||||
/* Irreversible until reset; unlike STOP, no sequence acknowledge can clear it. */
|
||||
void Motor_LatchSafetyInhibitFromIsr(uint16_t sequence);
|
||||
void Motor_StopAll(void);
|
||||
|
||||
/* A latched driver fault requires a power cycle before motion is accepted. */
|
||||
bool Motor_IsDriverFaultLatched(void);
|
||||
|
||||
uint8_t Motor0_GetPosition(motor_position_info_t *info);
|
||||
uint8_t Motor1_GetAngle(motor_position_info_t *info);
|
||||
uint8_t Motor2_GetAngle(motor_position_info_t *info);
|
||||
uint8_t Motor3_GetPosition(motor_position_info_t *info);
|
||||
uint8_t Motor0_MoveToPositionMmX100(uint32_t positionMmX100);
|
||||
uint8_t Motor1_MoveToAngleDegX100(uint32_t angleDegX100);
|
||||
uint8_t Motor2_MoveToAngleDegX100(uint32_t angleDegX100);
|
||||
uint8_t Motor3_MoveToPositionMmX100(uint32_t positionMmX100);
|
||||
uint8_t Motor0_SetSpeedPlan(uint32_t durationMs, uint32_t distanceMmX100);
|
||||
uint8_t Motor1_SetSpeedPlan(uint32_t durationMs, uint32_t angleDegX100);
|
||||
uint8_t Motor2_SetSpeedPlan(uint32_t durationMs, uint32_t angleDegX100);
|
||||
uint8_t Motor3_SetSpeedPlan(uint32_t durationMs, uint32_t distanceMmX100);
|
||||
|
||||
#endif /* MOTOR_CONTROL_H */
|
||||
Reference in New Issue
Block a user