feat: add seat firmware workbench and OTA delivery
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
/***************************************************************************//**
|
||||
* \file main_cm0plus.c
|
||||
*
|
||||
* CYT4BFBCJE rev_d CM0+ entry point for the passenger-seat timed-only ECU.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "cy_project.h"
|
||||
#include "cy_device_headers.h"
|
||||
#include "bsp_seat_backrest_heater.h"
|
||||
#include "bsp_seat_fan.h"
|
||||
#include "motor_control.h"
|
||||
#include "safety_manager.h"
|
||||
#include "seat_move_config.h"
|
||||
#include "seat_timed_application.h"
|
||||
|
||||
volatile uint32_t g_seatTimedResetReason = 0u;
|
||||
volatile uint32_t g_seatTimedInitResult = MOTOR_API_FAILURE;
|
||||
|
||||
static void SeatTimed_HoldSafeOff(void)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
Motor_ForceSafeOff();
|
||||
(void)BspSeatBackrestHeater_ForceOff();
|
||||
(void)BspSeatFan_ForceOff();
|
||||
SafetyManager_KickWatchdog();
|
||||
Cy_SysTick_DelayInUs(SEAT_MOVE_TASK_PERIOD_US);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
(void)BspSeatBackrestHeater_ForceOff();
|
||||
(void)BspSeatFan_ForceOff();
|
||||
SystemInit();
|
||||
|
||||
Motor_ForceSafeOff();
|
||||
if(!BspSeatBackrestHeater_ForceOff() || !BspSeatFan_ForceOff())
|
||||
{
|
||||
SeatTimed_HoldSafeOff();
|
||||
}
|
||||
|
||||
g_seatTimedResetReason = Cy_SysReset_GetResetReason();
|
||||
Cy_SysReset_ClearAllResetReasons();
|
||||
SafetyManager_Init(g_seatTimedResetReason);
|
||||
if(SafetyManager_IsInhibited())
|
||||
{
|
||||
SeatTimed_HoldSafeOff();
|
||||
}
|
||||
|
||||
__enable_irq();
|
||||
g_seatTimedInitResult = Motor_Init();
|
||||
if(g_seatTimedInitResult != MOTOR_API_SUCCESS)
|
||||
{
|
||||
SafetyManager_LatchFault(SAFETY_FAULT_DRIVER);
|
||||
SeatTimed_HoldSafeOff();
|
||||
}
|
||||
|
||||
Motor_SetWatchdogServiceEnabled(true);
|
||||
if(!SeatTimedApplication_Init())
|
||||
{
|
||||
SeatTimed_HoldSafeOff();
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
SeatTimedApplication_Service();
|
||||
if(SafetyManager_IsInhibited())
|
||||
{
|
||||
Motor_ForceSafeOff();
|
||||
(void)BspSeatBackrestHeater_ForceOff();
|
||||
(void)BspSeatFan_ForceOff();
|
||||
}
|
||||
SafetyManager_KickWatchdog();
|
||||
Cy_SysTick_DelayInUs(SEAT_MOVE_TASK_PERIOD_US);
|
||||
}
|
||||
}
|
||||
|
||||
/* [] END OF FILE */
|
||||
@@ -0,0 +1,332 @@
|
||||
#include "safety_manager.h"
|
||||
|
||||
#include "cy_project.h"
|
||||
#include "cy_device_headers.h"
|
||||
#include "motor_control.h"
|
||||
#include "seat_motor_manager.h"
|
||||
#include "seat_move_config.h"
|
||||
|
||||
#if defined(CoreDebug) && defined(CoreDebug_DHCSR_C_DEBUGEN_Msk)
|
||||
#define SAFETY_DEBUG_DETACH_SUPPORTED (1u)
|
||||
#else
|
||||
#define SAFETY_DEBUG_DETACH_SUPPORTED (0u)
|
||||
#endif
|
||||
|
||||
static volatile safety_fault_t latchedFault = SAFETY_FAULT_NONE;
|
||||
static bool watchdogReset = false;
|
||||
static bool watchdogInitialized = false;
|
||||
static bool hilWatchdogResetArmed = false;
|
||||
static bool hilWatchdogRecovered = false;
|
||||
#if (SAFETY_DEBUG_DETACH_SUPPORTED == 1u)
|
||||
static bool debuggerWasAttached = false;
|
||||
#endif
|
||||
|
||||
static bool SafetyManager_DebuggerAttached(void)
|
||||
{
|
||||
#if (SAFETY_DEBUG_DETACH_SUPPORTED == 1u)
|
||||
return ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0ul);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t SafetyManager_ReadDebugMarker(void)
|
||||
{
|
||||
return BACKUP->unBREG[SEAT_MOVE_DEBUG_SESSION_BREG_INDEX].u32Register;
|
||||
}
|
||||
|
||||
static bool SafetyManager_WriteDebugMarker(uint32_t marker)
|
||||
{
|
||||
BACKUP->unBREG[SEAT_MOVE_DEBUG_SESSION_BREG_INDEX].u32Register = marker;
|
||||
__DSB();
|
||||
return (SafetyManager_ReadDebugMarker() == marker);
|
||||
}
|
||||
|
||||
static bool SafetyManager_WaitForWatchdogState(bool enabled)
|
||||
{
|
||||
uint32_t remaining = 200ul;
|
||||
uint32_t expected = enabled ? 1ul : 0ul;
|
||||
|
||||
/* WDT ENABLE is an asynchronous request bit; ENABLED is the synchronized
|
||||
* LF-clock state. Configuration writes made before disable completes are
|
||||
* ignored by the hardware. */
|
||||
while((WDT->unCTL.stcField.u1ENABLED != expected) && (remaining > 0ul))
|
||||
{
|
||||
Cy_SysTick_DelayInUs(1u);
|
||||
remaining--;
|
||||
}
|
||||
return (WDT->unCTL.stcField.u1ENABLED == expected);
|
||||
}
|
||||
|
||||
static void SafetyManager_ClearHilWatchdogCredential(void)
|
||||
{
|
||||
BACKUP->unBREG[SEAT_MOVE_HIL_WDT_MAGIC_BREG_INDEX].u32Register = 0u;
|
||||
BACKUP->unBREG[SEAT_MOVE_HIL_WDT_TOKEN_BREG_INDEX].u32Register = 0u;
|
||||
BACKUP->unBREG[SEAT_MOVE_HIL_WDT_CHECK_BREG_INDEX].u32Register = 0u;
|
||||
__DSB();
|
||||
}
|
||||
|
||||
void SafetyManager_Init(uint32_t resetReason)
|
||||
{
|
||||
const uint32_t watchdogMask = CY_SYSRESET_WDT |
|
||||
CY_SYSRESET_MCWDT0 |
|
||||
CY_SYSRESET_MCWDT1 |
|
||||
CY_SYSRESET_MCWDT2 |
|
||||
CY_SYSRESET_MCWDT3;
|
||||
bool watchdogStopped;
|
||||
bool debuggerAttached;
|
||||
uint32_t marker;
|
||||
uint32_t hilMagic;
|
||||
uint32_t hilToken;
|
||||
uint32_t hilCheck;
|
||||
bool authorizedHilReset;
|
||||
bool markerOk = true;
|
||||
|
||||
/* A watchdog instance is retained across its own reset on this device.
|
||||
* Stop it before reading credentials or initializing peripherals; the
|
||||
* 100 ms bench timeout otherwise permits a reset loop. */
|
||||
Cy_WDT_Disable();
|
||||
watchdogStopped = SafetyManager_WaitForWatchdogState(false);
|
||||
|
||||
debuggerAttached = SafetyManager_DebuggerAttached();
|
||||
marker = SafetyManager_ReadDebugMarker();
|
||||
hilMagic = BACKUP->unBREG[
|
||||
SEAT_MOVE_HIL_WDT_MAGIC_BREG_INDEX].u32Register;
|
||||
hilToken = BACKUP->unBREG[
|
||||
SEAT_MOVE_HIL_WDT_TOKEN_BREG_INDEX].u32Register;
|
||||
hilCheck = BACKUP->unBREG[
|
||||
SEAT_MOVE_HIL_WDT_CHECK_BREG_INDEX].u32Register;
|
||||
authorizedHilReset =
|
||||
(hilMagic == SEAT_MOVE_HIL_WDT_MARKER) &&
|
||||
(hilCheck == (hilMagic ^ hilToken ^ 0xFFFFFFFFu)) &&
|
||||
(((resetReason & watchdogMask) != 0ul) ||
|
||||
((resetReason & CY_SYSRESET_SOFT) != 0ul));
|
||||
|
||||
latchedFault = SAFETY_FAULT_NONE;
|
||||
watchdogInitialized = false;
|
||||
hilWatchdogResetArmed = false;
|
||||
watchdogReset = ((resetReason & watchdogMask) != 0ul) ||
|
||||
authorizedHilReset;
|
||||
hilWatchdogRecovered = authorizedHilReset;
|
||||
if((resetReason & CY_SYSRESET_PORVDDD) != 0ul)
|
||||
{
|
||||
markerOk = SafetyManager_WriteDebugMarker(0u);
|
||||
marker = SafetyManager_ReadDebugMarker();
|
||||
SafetyManager_ClearHilWatchdogCredential();
|
||||
hilWatchdogRecovered = false;
|
||||
}
|
||||
else if(hilWatchdogRecovered)
|
||||
{
|
||||
/* Consume before CAN comes online: transport retries cannot turn one
|
||||
* authenticated reset into a second physical reset. */
|
||||
SafetyManager_ClearHilWatchdogCredential();
|
||||
}
|
||||
else if(hilMagic == SEAT_MOVE_HIL_WDT_MARKER)
|
||||
{
|
||||
/* XRES/programming without a valid reset reason is not completion. */
|
||||
SafetyManager_ClearHilWatchdogCredential();
|
||||
}
|
||||
#if (SAFETY_DEBUG_DETACH_SUPPORTED == 1u)
|
||||
debuggerWasAttached = debuggerAttached;
|
||||
#endif
|
||||
|
||||
if(!markerOk || (marker == SEAT_MOVE_DEBUG_EXIT_MAGIC) ||
|
||||
((marker == SEAT_MOVE_DEBUG_ACTIVE_MAGIC) && !debuggerAttached))
|
||||
{
|
||||
latchedFault = SAFETY_FAULT_DEBUG_DETACH;
|
||||
}
|
||||
else if(watchdogReset && !hilWatchdogRecovered)
|
||||
{
|
||||
latchedFault = SAFETY_FAULT_BOOT_RECOVERY;
|
||||
}
|
||||
else if(debuggerAttached &&
|
||||
!SafetyManager_WriteDebugMarker(SEAT_MOVE_DEBUG_ACTIVE_MAGIC))
|
||||
{
|
||||
latchedFault = SAFETY_FAULT_DEBUG_DETACH;
|
||||
}
|
||||
|
||||
/* The system-WDT configuration register is retained across some reset
|
||||
* paths and AUTO_SERVICE is not reset by Cy_WDT_Init(). If that bit is
|
||||
* left enabled, stopping the two software service paths can never prove a
|
||||
* real watchdog reset because hardware services the counter at WARN_LIMIT.
|
||||
* Configure only while stopped, and make software the sole WDT owner. */
|
||||
if(!watchdogStopped)
|
||||
{
|
||||
latchedFault = SAFETY_FAULT_DRIVER;
|
||||
return;
|
||||
}
|
||||
Cy_WDT_Init();
|
||||
Cy_WDT_Unlock();
|
||||
Cy_WDT_SetUpperLimit(SEAT_MOVE_WDT_TIMEOUT_TICKS);
|
||||
Cy_WDT_SetUpperAction(CY_WDT_LOW_UPP_ACTION_RESET);
|
||||
Cy_WDT_SetWarnAction(CY_WDT_WARN_ACTION_NONE);
|
||||
Cy_WDT_SetAutoService(CY_WDT_DISABLE);
|
||||
Cy_WDT_SetDebugRun(CY_WDT_ENABLE);
|
||||
Cy_WDT_Lock();
|
||||
if((WDT->unUPPER_LIMIT.stcField.u32UPPER_LIMIT !=
|
||||
SEAT_MOVE_WDT_TIMEOUT_TICKS) ||
|
||||
(WDT->unCONFIG.stcField.u1UPPER_ACTION !=
|
||||
(uint32_t)CY_WDT_LOW_UPP_ACTION_RESET) ||
|
||||
(WDT->unCONFIG.stcField.u1AUTO_SERVICE !=
|
||||
(uint32_t)CY_WDT_DISABLE))
|
||||
{
|
||||
latchedFault = SAFETY_FAULT_DRIVER;
|
||||
return;
|
||||
}
|
||||
Cy_WDT_Enable();
|
||||
if(!SafetyManager_WaitForWatchdogState(true))
|
||||
{
|
||||
latchedFault = SAFETY_FAULT_DRIVER;
|
||||
return;
|
||||
}
|
||||
Cy_WDT_ClearWatchdog();
|
||||
Cy_SysTick_DelayInUs(1000u);
|
||||
if(Cy_WDT_GetCount() == 0ul)
|
||||
{
|
||||
latchedFault = SAFETY_FAULT_DRIVER;
|
||||
return;
|
||||
}
|
||||
watchdogInitialized = true;
|
||||
SafetyManager_KickWatchdog();
|
||||
}
|
||||
|
||||
void SafetyManager_KickWatchdog(void)
|
||||
{
|
||||
if((false != watchdogInitialized) && !hilWatchdogResetArmed)
|
||||
{
|
||||
Cy_WDT_ClearWatchdog();
|
||||
}
|
||||
}
|
||||
|
||||
bool SafetyManager_IsWatchdogInitialized(void)
|
||||
{
|
||||
return watchdogInitialized;
|
||||
}
|
||||
|
||||
void SafetyManager_LatchFault(safety_fault_t fault)
|
||||
{
|
||||
if((fault != SAFETY_FAULT_NONE) &&
|
||||
(latchedFault == SAFETY_FAULT_NONE))
|
||||
{
|
||||
latchedFault = fault;
|
||||
Motor_LatchSafetyInhibitFromIsr(0u);
|
||||
Motor_StopAll();
|
||||
SeatMotorManager_StopAll(0ul);
|
||||
}
|
||||
}
|
||||
|
||||
void SafetyManager_Service(void)
|
||||
{
|
||||
bool debuggerAttached = SafetyManager_DebuggerAttached();
|
||||
uint32_t marker = SafetyManager_ReadDebugMarker();
|
||||
|
||||
if(marker == SEAT_MOVE_DEBUG_EXIT_MAGIC)
|
||||
{
|
||||
SafetyManager_LatchFault(SAFETY_FAULT_DEBUG_DETACH);
|
||||
}
|
||||
|
||||
if(Motor_IsDriverFaultLatched())
|
||||
{
|
||||
SafetyManager_LatchFault(SAFETY_FAULT_DRIVER);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No newly observed driver fault. */
|
||||
}
|
||||
|
||||
#if (SAFETY_DEBUG_DETACH_SUPPORTED == 1u)
|
||||
if(debuggerAttached)
|
||||
{
|
||||
if((marker != SEAT_MOVE_DEBUG_ACTIVE_MAGIC) &&
|
||||
!SafetyManager_WriteDebugMarker(SEAT_MOVE_DEBUG_ACTIVE_MAGIC))
|
||||
{
|
||||
SafetyManager_LatchFault(SAFETY_FAULT_DEBUG_DETACH);
|
||||
}
|
||||
debuggerWasAttached = true;
|
||||
}
|
||||
else if(debuggerWasAttached)
|
||||
{
|
||||
SafetyManager_LatchFault(SAFETY_FAULT_DEBUG_DETACH);
|
||||
debuggerWasAttached = false;
|
||||
}
|
||||
#else
|
||||
(void)debuggerAttached;
|
||||
#endif
|
||||
|
||||
SafetyManager_KickWatchdog();
|
||||
}
|
||||
|
||||
bool SafetyManager_IsInhibited(void)
|
||||
{
|
||||
return (latchedFault != SAFETY_FAULT_NONE);
|
||||
}
|
||||
|
||||
safety_fault_t SafetyManager_GetFault(void)
|
||||
{
|
||||
return latchedFault;
|
||||
}
|
||||
|
||||
bool SafetyManager_WasWatchdogReset(void)
|
||||
{
|
||||
return watchdogReset;
|
||||
}
|
||||
|
||||
bool SafetyManager_TriggerHilWatchdogReset(uint16_t token)
|
||||
{
|
||||
uint32_t check;
|
||||
|
||||
if(!watchdogInitialized || hilWatchdogResetArmed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
BACKUP->unBREG[SEAT_MOVE_HIL_WDT_MAGIC_BREG_INDEX].u32Register =
|
||||
SEAT_MOVE_HIL_WDT_MARKER;
|
||||
BACKUP->unBREG[SEAT_MOVE_HIL_WDT_TOKEN_BREG_INDEX].u32Register = token;
|
||||
check = SEAT_MOVE_HIL_WDT_MARKER ^ (uint32_t)token ^ 0xFFFFFFFFu;
|
||||
BACKUP->unBREG[SEAT_MOVE_HIL_WDT_CHECK_BREG_INDEX].u32Register = check;
|
||||
__DSB();
|
||||
if((BACKUP->unBREG[
|
||||
SEAT_MOVE_HIL_WDT_MAGIC_BREG_INDEX].u32Register !=
|
||||
SEAT_MOVE_HIL_WDT_MARKER) ||
|
||||
(BACKUP->unBREG[
|
||||
SEAT_MOVE_HIL_WDT_CHECK_BREG_INDEX].u32Register != check))
|
||||
{
|
||||
SafetyManager_ClearHilWatchdogCredential();
|
||||
return false;
|
||||
}
|
||||
/* Long-running motor calibration/coast loops normally service WDT
|
||||
* directly so they remain safe even while the application loop is busy.
|
||||
* The armed HIL case must suspend both service paths or a real watchdog
|
||||
* reset can never occur. Startup re-enables this after the reset. */
|
||||
Motor_SetWatchdogServiceEnabled(false);
|
||||
Cy_WDT_ClearWatchdog();
|
||||
hilWatchdogResetArmed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SafetyManager_CommitHilWatchdogReset(void)
|
||||
{
|
||||
if(!hilWatchdogResetArmed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* This bench's connected CMSIS-DAP can suppress the WDT reset output even
|
||||
* after C-SPY detaches. First prove physical WDT expiry, then use the
|
||||
* reference project's authenticated processor-reset fallback. */
|
||||
while(Cy_WDT_GetCount() < SEAT_MOVE_WDT_TIMEOUT_TICKS)
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
__DSB();
|
||||
NVIC_SystemReset();
|
||||
for(;;)
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
bool SafetyManager_WasHilWatchdogRecovered(void)
|
||||
{
|
||||
return hilWatchdogRecovered;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef SAFETY_MANAGER_H
|
||||
#define SAFETY_MANAGER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SAFETY_FAULT_NONE = 0,
|
||||
SAFETY_FAULT_DRIVER = 1,
|
||||
SAFETY_FAULT_CAN_BUS_OFF = 2,
|
||||
SAFETY_FAULT_CONFIG_STORE = 3,
|
||||
SAFETY_FAULT_BOOT_RECOVERY = 4,
|
||||
SAFETY_FAULT_DEBUG_DETACH = 5,
|
||||
SAFETY_FAULT_CAN_INIT = 6
|
||||
} safety_fault_t;
|
||||
|
||||
void SafetyManager_Init(uint32_t resetReason);
|
||||
void SafetyManager_Service(void);
|
||||
void SafetyManager_LatchFault(safety_fault_t fault);
|
||||
void SafetyManager_KickWatchdog(void);
|
||||
bool SafetyManager_IsWatchdogInitialized(void);
|
||||
bool SafetyManager_IsInhibited(void);
|
||||
safety_fault_t SafetyManager_GetFault(void);
|
||||
bool SafetyManager_WasWatchdogReset(void);
|
||||
bool SafetyManager_TriggerHilWatchdogReset(uint16_t token);
|
||||
void SafetyManager_CommitHilWatchdogReset(void);
|
||||
bool SafetyManager_WasHilWatchdogRecovered(void);
|
||||
|
||||
#endif /* SAFETY_MANAGER_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,154 @@
|
||||
#ifndef SEAT_MOTOR_MANAGER_H
|
||||
#define SEAT_MOTOR_MANAGER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "motor_control.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SEAT_MOTOR_TASK_IDLE = 0,
|
||||
SEAT_MOTOR_TASK_WAIT_START,
|
||||
SEAT_MOTOR_TASK_POSITION,
|
||||
SEAT_MOTOR_TASK_TIMED,
|
||||
SEAT_MOTOR_TASK_RETRY_DELAY,
|
||||
SEAT_MOTOR_TASK_RANGE_CALIBRATION,
|
||||
SEAT_MOTOR_TASK_SPEED_CAL_WARMUP,
|
||||
SEAT_MOTOR_TASK_SPEED_CAL_MEASURE,
|
||||
SEAT_MOTOR_TASK_SPEED_CAL_SETTLE,
|
||||
SEAT_MOTOR_TASK_COMPLETE,
|
||||
SEAT_MOTOR_TASK_FAILED
|
||||
} seat_motor_task_state_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SEAT_MOTOR_RESULT_NONE = 0,
|
||||
SEAT_MOTOR_RESULT_RUNNING,
|
||||
SEAT_MOTOR_RESULT_OK,
|
||||
SEAT_MOTOR_RESULT_STOPPED,
|
||||
SEAT_MOTOR_RESULT_STALL,
|
||||
SEAT_MOTOR_RESULT_ENDPOINT,
|
||||
SEAT_MOTOR_RESULT_TIMEOUT,
|
||||
SEAT_MOTOR_RESULT_DRIVER_FAULT,
|
||||
SEAT_MOTOR_RESULT_INVALID,
|
||||
SEAT_MOTOR_RESULT_CALIBRATION_FAILED
|
||||
} seat_motor_result_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
seat_motor_task_state_t taskState;
|
||||
seat_motor_result_t result;
|
||||
motor_event_t lastMotorEvent;
|
||||
motor_direction_t direction;
|
||||
uint32_t commandSequence;
|
||||
uint32_t valueX100;
|
||||
uint32_t hallCount;
|
||||
uint32_t maxHallCount;
|
||||
uint32_t maxSpeedPpsX100;
|
||||
uint32_t hallSpeedPpsX100;
|
||||
uint32_t positionPercentX100;
|
||||
uint32_t positionMmX100;
|
||||
uint32_t horizontalMmX100;
|
||||
uint32_t verticalMmX100;
|
||||
uint32_t angleDegX100;
|
||||
uint8_t dutyPercent;
|
||||
uint8_t retryCount;
|
||||
bool active;
|
||||
bool retried;
|
||||
bool positionValid;
|
||||
} seat_motor_status_t;
|
||||
|
||||
void SeatMotorManager_Init(void);
|
||||
void SeatMotorManager_Service(void);
|
||||
void SeatMotorManager_Stop(motor_mode_t mode, uint32_t commandSequence);
|
||||
void SeatMotorManager_StopAll(uint32_t commandSequence);
|
||||
bool SeatMotorManager_IsAnyActive(void);
|
||||
bool SeatMotorManager_GetStatus(motor_mode_t mode,
|
||||
seat_motor_status_t *status);
|
||||
|
||||
/* Six standardized, non-blocking motion primitives. Physical values are x100. */
|
||||
bool SeatMotor_MoveAbsoluteDuty(motor_mode_t mode,
|
||||
uint32_t targetValueX100,
|
||||
uint8_t dutyPercent,
|
||||
uint32_t commandSequence);
|
||||
bool SeatMotor_MoveAbsoluteNormalized(motor_mode_t mode,
|
||||
uint32_t targetPercentX100,
|
||||
uint32_t timeoutMs,
|
||||
uint8_t dutyPercent,
|
||||
uint32_t commandSequence);
|
||||
bool SeatMotor_MoveRelativeNormalized(motor_mode_t mode,
|
||||
int32_t deltaPercentX100,
|
||||
uint32_t timeoutMs,
|
||||
uint8_t dutyPercent,
|
||||
uint32_t commandSequence);
|
||||
bool SeatMotor_MoveRelativeDuty(motor_mode_t mode,
|
||||
int32_t deltaValueX100,
|
||||
uint8_t dutyPercent,
|
||||
uint32_t commandSequence);
|
||||
bool SeatMotor_MoveTimedDuty(motor_mode_t mode,
|
||||
motor_direction_t direction,
|
||||
uint32_t durationMs,
|
||||
uint8_t dutyPercent,
|
||||
uint32_t commandSequence);
|
||||
bool SeatMotor_MoveAbsoluteSpeed(motor_mode_t mode,
|
||||
uint32_t targetValueX100,
|
||||
uint32_t speedValuePerSecondX100,
|
||||
uint32_t commandSequence);
|
||||
bool SeatMotor_MoveRelativeSpeed(motor_mode_t mode,
|
||||
int32_t deltaValueX100,
|
||||
uint32_t speedValuePerSecondX100,
|
||||
uint32_t commandSequence);
|
||||
bool SeatMotor_MoveTimedSpeed(motor_mode_t mode,
|
||||
motor_direction_t direction,
|
||||
uint32_t durationMs,
|
||||
uint32_t speedValuePerSecondX100,
|
||||
uint32_t commandSequence);
|
||||
|
||||
/* Position command with an explicit requested arrival time. */
|
||||
bool SeatMotor_MoveAbsoluteInTime(motor_mode_t mode,
|
||||
uint32_t targetValueX100,
|
||||
uint32_t durationMs,
|
||||
uint32_t commandSequence);
|
||||
/* Keep the same speed plan while allowing a bounded scheduler/settling grace
|
||||
* before the manager reports TIMEOUT. */
|
||||
bool SeatMotor_MoveAbsoluteInTimeWithGrace(motor_mode_t mode,
|
||||
uint32_t targetValueX100,
|
||||
uint32_t durationMs,
|
||||
uint32_t deadlineGraceMs,
|
||||
uint32_t commandSequence);
|
||||
|
||||
/* Hall-coordinate variants used by firmware-owned synchronized trajectories.
|
||||
* The target is checked against the live calibrated MaxHall before conversion
|
||||
* to the motor's physical value. */
|
||||
bool SeatMotor_MoveAbsoluteHallDuty(motor_mode_t mode,
|
||||
uint32_t targetHallCount,
|
||||
uint8_t dutyPercent,
|
||||
uint32_t commandSequence);
|
||||
bool SeatMotor_MoveAbsoluteHallInTime(motor_mode_t mode,
|
||||
uint32_t targetHallCount,
|
||||
uint32_t durationMs,
|
||||
uint32_t commandSequence);
|
||||
bool SeatMotor_MoveAbsoluteHallInTimeWithGrace(motor_mode_t mode,
|
||||
uint32_t targetHallCount,
|
||||
uint32_t durationMs,
|
||||
uint32_t deadlineGraceMs,
|
||||
uint32_t commandSequence);
|
||||
|
||||
/* Range calibration is interruptible by Motor_RequestAbortAllFromIsr(). */
|
||||
bool SeatMotor_CalibrateRange(motor_mode_t mode,
|
||||
uint32_t legTimeoutMs,
|
||||
uint32_t commandSequence);
|
||||
/* Re-establish zero at the known near endpoint while retaining the confirmed
|
||||
* default MaxHall. This performs one near-seek only, not a full-range test. */
|
||||
bool SeatMotor_HomeKnownRange(motor_mode_t mode,
|
||||
uint32_t legTimeoutMs,
|
||||
uint32_t commandSequence);
|
||||
bool SeatMotor_StartMaximumSpeedCalibration(motor_mode_t mode,
|
||||
uint32_t commandSequence);
|
||||
bool SeatMotorManager_ClearFault(motor_mode_t mode);
|
||||
|
||||
/* Optional endpoint-based position recovery primitive. */
|
||||
bool SeatMotor_RecoverPosition(motor_mode_t mode, uint32_t savedHallCount);
|
||||
|
||||
#endif /* SEAT_MOTOR_MANAGER_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
#ifndef SEAT_TIMED_APPLICATION_H
|
||||
#define SEAT_TIMED_APPLICATION_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
bool SeatTimedApplication_Init(void);
|
||||
void SeatTimedApplication_Service(void);
|
||||
void SeatTimedApplication_StopAll(uint16_t sequence);
|
||||
|
||||
#endif /* SEAT_TIMED_APPLICATION_H */
|
||||
@@ -0,0 +1,687 @@
|
||||
#include "bsp_seat_backrest_heater.h"
|
||||
|
||||
#include "cy_project.h"
|
||||
#include "cy_device_headers.h"
|
||||
#include "seat_backrest_heater_config.h"
|
||||
|
||||
static bool BspSeatBackrestHeater_ConfigClock(void);
|
||||
static uint32_t BspSeatBackrestHeater_DutyToCompare(uint32_t dutyPercent);
|
||||
static void BspSeatBackrestHeater_SetPinGpioLow(void);
|
||||
static bool BspSeatBackrestHeaterCan_ConfigClock(void);
|
||||
static bool BspSeatBackrestHeaterCan_ConfigPins(void);
|
||||
static void BspSeatBackrestHeaterCan_IrqHandler(void);
|
||||
static void BspSeatBackrestHeaterCan_RxCallback(
|
||||
bool rxFifoMessage,
|
||||
uint8_t rxBufferOrFifo,
|
||||
cy_stc_canfd_msg_t *message);
|
||||
|
||||
static uint32_t s_heaterDutyPercent = 0u;
|
||||
|
||||
volatile uint32_t g_bspSeatBackrestHeaterStartFailStage = 0u;
|
||||
|
||||
volatile uint32_t g_bspSeatBackrestHeaterCanInitStatus =
|
||||
(uint32_t)CY_CANFD_SUCCESS;
|
||||
volatile uint32_t g_bspSeatBackrestHeaterCanRxCount = 0u;
|
||||
volatile uint32_t g_bspSeatBackrestHeaterCanRxQueueOverflowCount = 0u;
|
||||
volatile uint32_t g_bspSeatBackrestHeaterCanTxCount = 0u;
|
||||
volatile uint32_t g_bspSeatBackrestHeaterCanTxBusyCount = 0u;
|
||||
volatile uint32_t g_bspSeatBackrestHeaterCanLastRxId = 0u;
|
||||
volatile uint32_t g_bspSeatBackrestHeaterCanLastTxId = 0u;
|
||||
volatile uint32_t g_bspSeatBackrestHeaterCanLastTxStatus =
|
||||
(uint32_t)CY_CANFD_SUCCESS;
|
||||
|
||||
static volatile bsp_seat_backrest_heater_can_frame_t
|
||||
s_canRxQueue[SEAT_BACKREST_HEATER_CAN_RX_QUEUE_DEPTH];
|
||||
static volatile uint8_t s_canRxQueueHead = 0u;
|
||||
static volatile uint8_t s_canRxQueueTail = 0u;
|
||||
|
||||
static const cy_stc_id_filter_t s_canStandardIdFilters[] =
|
||||
{
|
||||
CANFD_CONFIG_STD_ID_FILTER_RANGE(
|
||||
SEAT_BACKREST_HEATER_CAN_CONTROL_29E_ID,
|
||||
SEAT_BACKREST_HEATER_CAN_CONTROL_29E_ID,
|
||||
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0),
|
||||
CANFD_CONFIG_STD_ID_FILTER_RANGE(
|
||||
SEAT_BACKREST_HEATER_CAN_CONFIG_2AA_ID,
|
||||
SEAT_BACKREST_HEATER_CAN_CONFIG_2AA_ID,
|
||||
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0),
|
||||
CANFD_CONFIG_STD_ID_FILTER_RANGE(
|
||||
SEAT_BACKREST_HEATER_CAN_MODE_3CE_ID,
|
||||
SEAT_BACKREST_HEATER_CAN_MODE_3CE_ID,
|
||||
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0),
|
||||
CANFD_CONFIG_STD_ID_FILTER_RANGE(
|
||||
SEAT_BACKREST_HEATER_CAN_SWITCH_42A_ID,
|
||||
SEAT_BACKREST_HEATER_CAN_SWITCH_42A_ID,
|
||||
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0),
|
||||
};
|
||||
|
||||
static cy_stc_sysint_irq_t s_canIrqConfig =
|
||||
{
|
||||
.sysIntSrc = SEAT_BACKREST_HEATER_CAN_IRQN,
|
||||
.intIdx = SEAT_BACKREST_HEATER_CAN_CPU_IRQ,
|
||||
.isEnabled = true,
|
||||
};
|
||||
|
||||
static cy_stc_canfd_config_t s_canConfig =
|
||||
{
|
||||
.txCallback = NULL,
|
||||
.rxCallback = BspSeatBackrestHeaterCan_RxCallback,
|
||||
.rxFifoWithTopCallback = NULL,
|
||||
.statusCallback = NULL,
|
||||
.errorCallback = NULL,
|
||||
.canFDMode = false,
|
||||
.bitrate =
|
||||
{
|
||||
/* 40 MHz / (10 * (1 + 5 + 2)) = 500 kbit/s. */
|
||||
.prescaler = 10u - 1u,
|
||||
.timeSegment1 = 5u - 1u,
|
||||
.timeSegment2 = 2u - 1u,
|
||||
.syncJumpWidth = 2u - 1u,
|
||||
},
|
||||
.fastBitrate =
|
||||
{
|
||||
.prescaler = 0u,
|
||||
.timeSegment1 = 0u,
|
||||
.timeSegment2 = 0u,
|
||||
.syncJumpWidth = 0u,
|
||||
},
|
||||
.tdcConfig =
|
||||
{
|
||||
.tdcEnabled = false,
|
||||
.tdcOffset = 0u,
|
||||
.tdcFilterWindow = 0u,
|
||||
},
|
||||
.sidFilterConfig =
|
||||
{
|
||||
.numberOfSIDFilters =
|
||||
sizeof(s_canStandardIdFilters) /
|
||||
sizeof(s_canStandardIdFilters[0]),
|
||||
.sidFilter = s_canStandardIdFilters,
|
||||
},
|
||||
.extidFilterConfig =
|
||||
{
|
||||
.numberOfEXTIDFilters = 0u,
|
||||
.extidFilter = NULL,
|
||||
.extIDANDMask = 0x1FFFFFFFu,
|
||||
},
|
||||
.globalFilterConfig =
|
||||
{
|
||||
.nonMatchingFramesStandard = CY_CANFD_REJECT_NON_MATCHING,
|
||||
.nonMatchingFramesExtended = CY_CANFD_REJECT_NON_MATCHING,
|
||||
.rejectRemoteFramesStandard = true,
|
||||
.rejectRemoteFramesExtended = true,
|
||||
},
|
||||
.rxBufferDataSize = CY_CANFD_BUFFER_DATA_SIZE_8,
|
||||
.rxFifo1DataSize = CY_CANFD_BUFFER_DATA_SIZE_8,
|
||||
.rxFifo0DataSize = CY_CANFD_BUFFER_DATA_SIZE_8,
|
||||
.txBufferDataSize = CY_CANFD_BUFFER_DATA_SIZE_8,
|
||||
.rxFifo0Config =
|
||||
{
|
||||
.mode = CY_CANFD_FIFO_MODE_BLOCKING,
|
||||
.watermark = 0u,
|
||||
.numberOfFifoElements =
|
||||
SEAT_BACKREST_HEATER_CAN_RX_FIFO0_ELEMENTS,
|
||||
.topPointerLogicEnabled = false,
|
||||
},
|
||||
.rxFifo1Config =
|
||||
{
|
||||
.mode = CY_CANFD_FIFO_MODE_BLOCKING,
|
||||
.watermark = 0u,
|
||||
.numberOfFifoElements = 0u,
|
||||
.topPointerLogicEnabled = false,
|
||||
},
|
||||
.noOfRxBuffers = 0u,
|
||||
.noOfTxBuffers = SEAT_BACKREST_HEATER_CAN_TX_BUFFER_COUNT,
|
||||
};
|
||||
|
||||
static const cy_stc_tcpwm_pwm_config_t s_heaterPwmConfig =
|
||||
{
|
||||
.pwmMode = CY_TCPWM_PWM_MODE_PWM,
|
||||
.clockPrescaler = CY_TCPWM_PRESCALER_DIVBY_1,
|
||||
.debug_pause = false,
|
||||
.deadTime = 0u,
|
||||
.deadTimeComp = 0u,
|
||||
.runMode = CY_TCPWM_PWM_CONTINUOUS,
|
||||
.countDirection = CY_TCPWM_COUNTER_COUNT_UP,
|
||||
.cc0MatchMode = CY_TCPWM_PWM_TR_CTRL2_CLEAR,
|
||||
.overflowMode = CY_TCPWM_PWM_TR_CTRL2_SET,
|
||||
.underflowMode = CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE,
|
||||
.cc1MatchMode = CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE,
|
||||
.period = SEAT_BACKREST_HEATER_PWM_PERIOD_TICKS - 1u,
|
||||
.period_buff = 0u,
|
||||
.enablePeriodSwap = false,
|
||||
.enableLineSelSwap = false,
|
||||
.compare0 = 0u,
|
||||
.compare0_buff = 0u,
|
||||
.enableCompare0Swap = false,
|
||||
.compare1 = 0u,
|
||||
.compare1_buff = 0u,
|
||||
.enableCompare1Swap = false,
|
||||
.interruptSources = CY_TCPWM_INT_NONE,
|
||||
.invertPWMOut = 0u,
|
||||
.invertPWMOutN = 0u,
|
||||
.killMode = CY_TCPWM_PWM_STOP_ON_KILL,
|
||||
.switchInputMode = CY_TCPWM_INPUT_LEVEL,
|
||||
.switchInput = 0u,
|
||||
.reloadInputMode = CY_TCPWM_INPUT_LEVEL,
|
||||
.reloadInput = 0u,
|
||||
.startInputMode = CY_TCPWM_INPUT_LEVEL,
|
||||
.startInput = 0u,
|
||||
.kill0InputMode = CY_TCPWM_INPUT_LEVEL,
|
||||
.kill0Input = 0u,
|
||||
.kill1InputMode = CY_TCPWM_INPUT_LEVEL,
|
||||
.kill1Input = 0u,
|
||||
.countInputMode = CY_TCPWM_INPUT_LEVEL,
|
||||
.countInput = 1u,
|
||||
.immediateKill = true,
|
||||
.pwmOnDisable = CY_TCPWM_PWM_OUT_MODE_LOW,
|
||||
.trigger0EventCfg = CY_TCPWM_COUNTER_OVERFLOW,
|
||||
.trigger1EventCfg = CY_TCPWM_COUNTER_OVERFLOW,
|
||||
};
|
||||
|
||||
bool BspSeatBackrestHeater_ForceOff(void)
|
||||
{
|
||||
cy_stc_gpio_pin_config_t pinConfig =
|
||||
{
|
||||
.outVal = 0u,
|
||||
.driveMode = CY_GPIO_DM_STRONG_IN_OFF,
|
||||
.hsiom = SEAT_BACKREST_HEATER_PWM_GPIO_HSIOM,
|
||||
.intEdge = 0u,
|
||||
.intMask = 0u,
|
||||
.vtrip = 0u,
|
||||
.slewRate = 0u,
|
||||
.driveSel = CY_GPIO_DRIVE_FULL,
|
||||
};
|
||||
cy_en_gpio_status_t status;
|
||||
|
||||
status = Cy_GPIO_Pin_Init(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN,
|
||||
&pinConfig);
|
||||
Cy_GPIO_Write(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN,
|
||||
0u);
|
||||
s_heaterDutyPercent = 0u;
|
||||
|
||||
return ((status == CY_GPIO_SUCCESS) &&
|
||||
(Cy_GPIO_GetHSIOM(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN) ==
|
||||
SEAT_BACKREST_HEATER_PWM_GPIO_HSIOM));
|
||||
}
|
||||
|
||||
bool BspSeatBackrestHeater_InitPwm(void)
|
||||
{
|
||||
if(!BspSeatBackrestHeater_ConfigClock())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Cy_Tcpwm_Pwm_Disable(SEAT_BACKREST_HEATER_PWM_TCPWM);
|
||||
if(Cy_Tcpwm_Pwm_Init(SEAT_BACKREST_HEATER_PWM_TCPWM,
|
||||
&s_heaterPwmConfig) != CY_RET_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((Cy_Tcpwm_Pwm_GetPeriod(SEAT_BACKREST_HEATER_PWM_TCPWM) ==
|
||||
(SEAT_BACKREST_HEATER_PWM_PERIOD_TICKS - 1u)) &&
|
||||
(Cy_Tcpwm_Pwm_GetCompare0(SEAT_BACKREST_HEATER_PWM_TCPWM) == 0u));
|
||||
}
|
||||
|
||||
bool BspSeatBackrestHeater_Start(uint32_t dutyPercent)
|
||||
{
|
||||
g_bspSeatBackrestHeaterStartFailStage = 0u;
|
||||
if(!BspSeatBackrestHeater_SetDutyPercent(dutyPercent))
|
||||
{
|
||||
g_bspSeatBackrestHeaterStartFailStage = 1u;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* P16.7 remains GPIO low until the PWM counter is confirmed running. */
|
||||
Cy_GPIO_Write(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN,
|
||||
0u);
|
||||
Cy_Tcpwm_Pwm_SetCounter(SEAT_BACKREST_HEATER_PWM_TCPWM,
|
||||
SEAT_BACKREST_HEATER_PWM_PERIOD_TICKS - 1u);
|
||||
Cy_Tcpwm_Pwm_Enable(SEAT_BACKREST_HEATER_PWM_TCPWM);
|
||||
Cy_Tcpwm_TriggerStart(SEAT_BACKREST_HEATER_PWM_TCPWM);
|
||||
Cy_SysTick_DelayInUs(2u);
|
||||
|
||||
if((Cy_Tcpwm_Pwm_GetStatus(SEAT_BACKREST_HEATER_PWM_TCPWM) &
|
||||
TCPWM_GRP_CNT_STATUS_RUNNING_Msk) == 0u)
|
||||
{
|
||||
g_bspSeatBackrestHeaterStartFailStage = 2u;
|
||||
BspSeatBackrestHeater_FailSafeOff();
|
||||
return false;
|
||||
}
|
||||
|
||||
Cy_GPIO_SetDriveSel(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN,
|
||||
CY_GPIO_DRIVE_FULL);
|
||||
Cy_GPIO_SetDrivemode(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN,
|
||||
CY_GPIO_DM_STRONG_IN_OFF);
|
||||
Cy_GPIO_SetHSIOM(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN,
|
||||
SEAT_BACKREST_HEATER_PWM_HSIOM);
|
||||
|
||||
if(Cy_GPIO_GetHSIOM(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN) !=
|
||||
SEAT_BACKREST_HEATER_PWM_HSIOM)
|
||||
{
|
||||
g_bspSeatBackrestHeaterStartFailStage = 3u;
|
||||
BspSeatBackrestHeater_FailSafeOff();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BspSeatBackrestHeater_SetDutyPercent(uint32_t dutyPercent)
|
||||
{
|
||||
uint32_t compare;
|
||||
|
||||
/* A true OFF uses FailSafeOff, avoiding a possible zero-compare pulse. */
|
||||
if((dutyPercent == 0u) || (dutyPercent > 100u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
compare = BspSeatBackrestHeater_DutyToCompare(dutyPercent);
|
||||
Cy_Tcpwm_Pwm_SetCompare0(SEAT_BACKREST_HEATER_PWM_TCPWM, compare);
|
||||
|
||||
if(Cy_Tcpwm_Pwm_GetCompare0(SEAT_BACKREST_HEATER_PWM_TCPWM) != compare)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
s_heaterDutyPercent = dutyPercent;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BspSeatBackrestHeater_FailSafeOff(void)
|
||||
{
|
||||
Cy_Tcpwm_Pwm_Disable(SEAT_BACKREST_HEATER_PWM_TCPWM);
|
||||
BspSeatBackrestHeater_SetPinGpioLow();
|
||||
s_heaterDutyPercent = 0u;
|
||||
}
|
||||
|
||||
bool BspSeatBackrestHeater_IsRunning(void)
|
||||
{
|
||||
return ((Cy_Tcpwm_Pwm_GetStatus(SEAT_BACKREST_HEATER_PWM_TCPWM) &
|
||||
TCPWM_GRP_CNT_STATUS_RUNNING_Msk) != 0u);
|
||||
}
|
||||
|
||||
uint32_t BspSeatBackrestHeater_GetDutyPercent(void)
|
||||
{
|
||||
return s_heaterDutyPercent;
|
||||
}
|
||||
|
||||
bool BspSeatBackrestHeaterCan_Init(void)
|
||||
{
|
||||
cy_en_canfd_status_t canStatus;
|
||||
|
||||
if(!BspSeatBackrestHeaterCan_ConfigClock() ||
|
||||
!BspSeatBackrestHeaterCan_ConfigPins())
|
||||
{
|
||||
g_bspSeatBackrestHeaterCanInitStatus =
|
||||
(uint32_t)CY_CANFD_BAD_PARAM;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Cy_SysInt_InitIRQ(&s_canIrqConfig) != CY_SYSINT_SUCCESS)
|
||||
{
|
||||
g_bspSeatBackrestHeaterCanInitStatus =
|
||||
(uint32_t)CY_CANFD_BAD_PARAM;
|
||||
return false;
|
||||
}
|
||||
|
||||
Cy_SysInt_SetSystemIrqVector(s_canIrqConfig.sysIntSrc,
|
||||
BspSeatBackrestHeaterCan_IrqHandler);
|
||||
NVIC_SetPriority(s_canIrqConfig.intIdx, 0u);
|
||||
NVIC_ClearPendingIRQ(s_canIrqConfig.intIdx);
|
||||
|
||||
(void)Cy_CANFD_DeInit(SEAT_BACKREST_HEATER_CAN_TYPE);
|
||||
canStatus = Cy_CANFD_Init(SEAT_BACKREST_HEATER_CAN_TYPE, &s_canConfig);
|
||||
g_bspSeatBackrestHeaterCanInitStatus = (uint32_t)canStatus;
|
||||
if(canStatus != CY_CANFD_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
NVIC_EnableIRQ(s_canIrqConfig.intIdx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BspSeatBackrestHeaterCan_Read(
|
||||
bsp_seat_backrest_heater_can_frame_t *frame)
|
||||
{
|
||||
uint32_t interruptState;
|
||||
uint8_t tail;
|
||||
|
||||
if(frame == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
interruptState = Cy_SysLib_EnterCriticalSection();
|
||||
tail = s_canRxQueueTail;
|
||||
if(tail == s_canRxQueueHead)
|
||||
{
|
||||
Cy_SysLib_ExitCriticalSection(interruptState);
|
||||
return false;
|
||||
}
|
||||
|
||||
frame->identifier = s_canRxQueue[tail].identifier;
|
||||
frame->data0 = s_canRxQueue[tail].data0;
|
||||
frame->data1 = s_canRxQueue[tail].data1;
|
||||
frame->dlc = s_canRxQueue[tail].dlc;
|
||||
|
||||
tail++;
|
||||
if(tail >= SEAT_BACKREST_HEATER_CAN_RX_QUEUE_DEPTH)
|
||||
{
|
||||
tail = 0u;
|
||||
}
|
||||
s_canRxQueueTail = tail;
|
||||
Cy_SysLib_ExitCriticalSection(interruptState);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BspSeatBackrestHeaterCan_Send(uint32_t identifier,
|
||||
uint32_t data0,
|
||||
uint32_t data1)
|
||||
{
|
||||
cy_stc_canfd_msg_t message;
|
||||
uint8_t bufferIndex;
|
||||
uint8_t dataIndex;
|
||||
|
||||
if(identifier > 0x7FFu)
|
||||
{
|
||||
g_bspSeatBackrestHeaterCanLastTxStatus =
|
||||
(uint32_t)CY_CANFD_BAD_PARAM;
|
||||
return false;
|
||||
}
|
||||
|
||||
message.canFDFormat = false;
|
||||
message.idConfig.extended = false;
|
||||
message.idConfig.identifier = identifier;
|
||||
message.dataConfig.dataLengthCode = SEAT_BACKREST_HEATER_CAN_DLC;
|
||||
message.dataConfig.data[0] = data0;
|
||||
message.dataConfig.data[1] = data1;
|
||||
for(dataIndex = 2u;
|
||||
dataIndex < CY_CANFD_MESSAGE_DATA_BUFFER_SIZE;
|
||||
dataIndex++)
|
||||
{
|
||||
message.dataConfig.data[dataIndex] = 0u;
|
||||
}
|
||||
|
||||
for(bufferIndex = 0u;
|
||||
bufferIndex < SEAT_BACKREST_HEATER_CAN_TX_BUFFER_COUNT;
|
||||
bufferIndex++)
|
||||
{
|
||||
cy_en_canfd_tx_buffer_status_t bufferStatus =
|
||||
Cy_CANFD_GetTxBufferStatus(SEAT_BACKREST_HEATER_CAN_TYPE,
|
||||
bufferIndex);
|
||||
|
||||
if((bufferStatus != CY_CANFD_TX_BUFFER_PENDING) &&
|
||||
(bufferStatus != CY_CANFD_TX_BUFFER_CANCEL_REQUESTED))
|
||||
{
|
||||
cy_en_canfd_status_t sendStatus;
|
||||
|
||||
g_bspSeatBackrestHeaterCanLastTxId = identifier;
|
||||
sendStatus = Cy_CANFD_UpdateAndTransmitMsgBuffer(
|
||||
SEAT_BACKREST_HEATER_CAN_TYPE,
|
||||
bufferIndex,
|
||||
&message);
|
||||
g_bspSeatBackrestHeaterCanLastTxStatus = (uint32_t)sendStatus;
|
||||
if(sendStatus == CY_CANFD_SUCCESS)
|
||||
{
|
||||
g_bspSeatBackrestHeaterCanTxCount++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
g_bspSeatBackrestHeaterCanTxBusyCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool BspSeatBackrestHeaterCan_ConfigClock(void)
|
||||
{
|
||||
uint32_t periClockHz = 0u;
|
||||
uint32_t divider;
|
||||
uint32_t clockGroup;
|
||||
|
||||
if(Cy_SysClk_GetClkPeriFrequency(&periClockHz) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if((periClockHz < SEAT_BACKREST_HEATER_CAN_CLOCK_HZ) ||
|
||||
((periClockHz % SEAT_BACKREST_HEATER_CAN_CLOCK_HZ) != 0u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
divider = periClockHz / SEAT_BACKREST_HEATER_CAN_CLOCK_HZ;
|
||||
if((divider == 0u) || (divider > 256u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
clockGroup = Cy_SysClk_GetClockGroup(SEAT_BACKREST_HEATER_CAN_PCLK);
|
||||
if(Cy_SysClk_PeriphDisableDivider(
|
||||
clockGroup,
|
||||
CY_SYSCLK_DIV_8_BIT,
|
||||
SEAT_BACKREST_HEATER_CAN_DIVIDER_NUMBER) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_SysClk_PeriphAssignDivider(
|
||||
SEAT_BACKREST_HEATER_CAN_PCLK,
|
||||
CY_SYSCLK_DIV_8_BIT,
|
||||
SEAT_BACKREST_HEATER_CAN_DIVIDER_NUMBER) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_SysClk_PeriphSetDivider(
|
||||
clockGroup,
|
||||
CY_SYSCLK_DIV_8_BIT,
|
||||
SEAT_BACKREST_HEATER_CAN_DIVIDER_NUMBER,
|
||||
divider - 1u) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Cy_SysClk_PeriphEnableDivider(
|
||||
clockGroup,
|
||||
CY_SYSCLK_DIV_8_BIT,
|
||||
SEAT_BACKREST_HEATER_CAN_DIVIDER_NUMBER) ==
|
||||
CY_SYSCLK_SUCCESS);
|
||||
}
|
||||
|
||||
static bool BspSeatBackrestHeaterCan_ConfigPins(void)
|
||||
{
|
||||
cy_stc_gpio_pin_config_t rxConfig =
|
||||
{
|
||||
.outVal = 0u,
|
||||
.driveMode = CY_GPIO_DM_HIGHZ,
|
||||
.hsiom = SEAT_BACKREST_HEATER_CAN_RX_MUX,
|
||||
.intEdge = 0u,
|
||||
.intMask = 0u,
|
||||
.vtrip = 0u,
|
||||
.slewRate = 0u,
|
||||
.driveSel = 0u,
|
||||
};
|
||||
cy_stc_gpio_pin_config_t txConfig =
|
||||
{
|
||||
.outVal = 1u,
|
||||
.driveMode = CY_GPIO_DM_STRONG,
|
||||
.hsiom = SEAT_BACKREST_HEATER_CAN_TX_MUX,
|
||||
.intEdge = 0u,
|
||||
.intMask = 0u,
|
||||
.vtrip = 0u,
|
||||
.slewRate = 0u,
|
||||
.driveSel = 0u,
|
||||
};
|
||||
cy_stc_gpio_pin_config_t transceiverConfig =
|
||||
{
|
||||
.outVal = SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_ENABLE,
|
||||
.driveMode = CY_GPIO_DM_STRONG_IN_OFF,
|
||||
.hsiom = SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_GPIO_HSIOM,
|
||||
.intEdge = 0u,
|
||||
.intMask = 0u,
|
||||
.vtrip = 0u,
|
||||
.slewRate = 0u,
|
||||
.driveSel = CY_GPIO_DRIVE_FULL,
|
||||
};
|
||||
|
||||
if(Cy_GPIO_Pin_Init(SEAT_BACKREST_HEATER_CAN_RX_PORT,
|
||||
SEAT_BACKREST_HEATER_CAN_RX_PIN,
|
||||
&rxConfig) != CY_GPIO_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_GPIO_Pin_Init(SEAT_BACKREST_HEATER_CAN_TX_PORT,
|
||||
SEAT_BACKREST_HEATER_CAN_TX_PIN,
|
||||
&txConfig) != CY_GPIO_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_GPIO_Pin_Init(SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_PORT,
|
||||
SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_PIN,
|
||||
&transceiverConfig) != CY_GPIO_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Cy_GPIO_Write(SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_PORT,
|
||||
SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_PIN,
|
||||
SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_ENABLE);
|
||||
Cy_SysTick_DelayInUs(1000u);
|
||||
|
||||
return (Cy_GPIO_ReadOut(SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_PORT,
|
||||
SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_PIN) ==
|
||||
SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_ENABLE);
|
||||
}
|
||||
|
||||
static void BspSeatBackrestHeaterCan_IrqHandler(void)
|
||||
{
|
||||
Cy_CANFD_IrqHandler(SEAT_BACKREST_HEATER_CAN_TYPE);
|
||||
}
|
||||
|
||||
static void BspSeatBackrestHeaterCan_RxCallback(
|
||||
bool rxFifoMessage,
|
||||
uint8_t rxBufferOrFifo,
|
||||
cy_stc_canfd_msg_t *message)
|
||||
{
|
||||
uint8_t head;
|
||||
uint8_t nextHead;
|
||||
|
||||
(void)rxFifoMessage;
|
||||
(void)rxBufferOrFifo;
|
||||
|
||||
if((message == NULL) || message->idConfig.extended || message->canFDFormat)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_bspSeatBackrestHeaterCanRxCount++;
|
||||
g_bspSeatBackrestHeaterCanLastRxId = message->idConfig.identifier;
|
||||
|
||||
head = s_canRxQueueHead;
|
||||
nextHead = head + 1u;
|
||||
if(nextHead >= SEAT_BACKREST_HEATER_CAN_RX_QUEUE_DEPTH)
|
||||
{
|
||||
nextHead = 0u;
|
||||
}
|
||||
|
||||
if(nextHead == s_canRxQueueTail)
|
||||
{
|
||||
g_bspSeatBackrestHeaterCanRxQueueOverflowCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
s_canRxQueue[head].identifier = message->idConfig.identifier;
|
||||
s_canRxQueue[head].dlc = message->dataConfig.dataLengthCode;
|
||||
s_canRxQueue[head].data0 = message->dataConfig.data[0];
|
||||
s_canRxQueue[head].data1 = message->dataConfig.data[1];
|
||||
s_canRxQueueHead = nextHead;
|
||||
}
|
||||
|
||||
static bool BspSeatBackrestHeater_ConfigClock(void)
|
||||
{
|
||||
uint32_t periClockHz = 0u;
|
||||
uint32_t divider;
|
||||
uint32_t clockGroup;
|
||||
|
||||
if(Cy_SysClk_GetClkPeriFrequency(&periClockHz) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if((periClockHz < SEAT_BACKREST_HEATER_COUNTER_CLOCK_HZ) ||
|
||||
((periClockHz % SEAT_BACKREST_HEATER_COUNTER_CLOCK_HZ) != 0u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
divider = periClockHz / SEAT_BACKREST_HEATER_COUNTER_CLOCK_HZ;
|
||||
if((divider == 0u) || (divider > 65536u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
clockGroup = Cy_SysClk_GetClockGroup(SEAT_BACKREST_HEATER_PWM_PCLK);
|
||||
if(Cy_SysClk_PeriphDisableDivider(clockGroup,
|
||||
CY_SYSCLK_DIV_16_BIT,
|
||||
SEAT_BACKREST_HEATER_PWM_DIVIDER_NUMBER) !=
|
||||
CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_SysClk_PeriphAssignDivider(SEAT_BACKREST_HEATER_PWM_PCLK,
|
||||
CY_SYSCLK_DIV_16_BIT,
|
||||
SEAT_BACKREST_HEATER_PWM_DIVIDER_NUMBER) !=
|
||||
CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_SysClk_PeriphSetDivider(clockGroup,
|
||||
CY_SYSCLK_DIV_16_BIT,
|
||||
SEAT_BACKREST_HEATER_PWM_DIVIDER_NUMBER,
|
||||
divider - 1u) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Cy_SysClk_PeriphEnableDivider(clockGroup,
|
||||
CY_SYSCLK_DIV_16_BIT,
|
||||
SEAT_BACKREST_HEATER_PWM_DIVIDER_NUMBER) ==
|
||||
CY_SYSCLK_SUCCESS);
|
||||
}
|
||||
|
||||
static uint32_t BspSeatBackrestHeater_DutyToCompare(uint32_t dutyPercent)
|
||||
{
|
||||
return (SEAT_BACKREST_HEATER_PWM_PERIOD_TICKS * dutyPercent) / 100u;
|
||||
}
|
||||
|
||||
static void BspSeatBackrestHeater_SetPinGpioLow(void)
|
||||
{
|
||||
Cy_GPIO_Write(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN,
|
||||
0u);
|
||||
Cy_GPIO_SetHSIOM(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN,
|
||||
SEAT_BACKREST_HEATER_PWM_GPIO_HSIOM);
|
||||
Cy_GPIO_SetDriveSel(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN,
|
||||
CY_GPIO_DRIVE_FULL);
|
||||
Cy_GPIO_SetDrivemode(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN,
|
||||
CY_GPIO_DM_STRONG_IN_OFF);
|
||||
Cy_GPIO_Write(SEAT_BACKREST_HEATER_PWM_PORT,
|
||||
SEAT_BACKREST_HEATER_PWM_PIN,
|
||||
0u);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#ifndef BSP_SEAT_BACKREST_HEATER_H
|
||||
#define BSP_SEAT_BACKREST_HEATER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t identifier;
|
||||
uint32_t data0;
|
||||
uint32_t data1;
|
||||
uint8_t dlc;
|
||||
} bsp_seat_backrest_heater_can_frame_t;
|
||||
|
||||
/* Force the BTS7010 IN path to GPIO low before PWM initialization. */
|
||||
bool BspSeatBackrestHeater_ForceOff(void);
|
||||
|
||||
/* Configure TCPWM1 counter 65 while P16.7 remains a strong GPIO low. */
|
||||
bool BspSeatBackrestHeater_InitPwm(void);
|
||||
|
||||
/* Start a non-zero PWM duty, then connect P16.7 to TCPWM line 65. */
|
||||
bool BspSeatBackrestHeater_Start(uint32_t dutyPercent);
|
||||
|
||||
/* Change a running non-zero duty. Use FailSafeOff for a true 0% output. */
|
||||
bool BspSeatBackrestHeater_SetDutyPercent(uint32_t dutyPercent);
|
||||
|
||||
/* Disable TCPWM and restore P16.7 to strong GPIO low. */
|
||||
void BspSeatBackrestHeater_FailSafeOff(void);
|
||||
|
||||
bool BspSeatBackrestHeater_IsRunning(void);
|
||||
uint32_t BspSeatBackrestHeater_GetDutyPercent(void);
|
||||
|
||||
/*
|
||||
* Start-path diagnostic for bench/HIL fault isolation.
|
||||
* 0 = no start failure, 1 = duty/compare write, 2 = counter did not run,
|
||||
* 3 = P16.7 HSIOM switch/readback.
|
||||
*/
|
||||
extern volatile uint32_t g_bspSeatBackrestHeaterStartFailStage;
|
||||
|
||||
/* Initialize the proven CAN4/TJA1044 board interface at 500 kbit/s. */
|
||||
bool BspSeatBackrestHeaterCan_Init(void);
|
||||
|
||||
/* Pop one received standard Classic CAN frame from the interrupt-safe queue. */
|
||||
bool BspSeatBackrestHeaterCan_Read(
|
||||
bsp_seat_backrest_heater_can_frame_t *frame);
|
||||
|
||||
/* Send one 8-byte standard Classic CAN frame. */
|
||||
bool BspSeatBackrestHeaterCan_Send(uint32_t identifier,
|
||||
uint32_t data0,
|
||||
uint32_t data1);
|
||||
|
||||
/* Watch-window diagnostics for CAN hardware integration. */
|
||||
extern volatile uint32_t g_bspSeatBackrestHeaterCanInitStatus;
|
||||
extern volatile uint32_t g_bspSeatBackrestHeaterCanRxCount;
|
||||
extern volatile uint32_t g_bspSeatBackrestHeaterCanRxQueueOverflowCount;
|
||||
extern volatile uint32_t g_bspSeatBackrestHeaterCanTxCount;
|
||||
extern volatile uint32_t g_bspSeatBackrestHeaterCanTxBusyCount;
|
||||
extern volatile uint32_t g_bspSeatBackrestHeaterCanLastRxId;
|
||||
extern volatile uint32_t g_bspSeatBackrestHeaterCanLastTxId;
|
||||
extern volatile uint32_t g_bspSeatBackrestHeaterCanLastTxStatus;
|
||||
|
||||
#endif /* BSP_SEAT_BACKREST_HEATER_H */
|
||||
@@ -0,0 +1,332 @@
|
||||
#include "bsp_seat_current_adc.h"
|
||||
|
||||
#include "cy_project.h"
|
||||
#include "cy_device_headers.h"
|
||||
#include "seat_current_adc_config.h"
|
||||
|
||||
#define SEAT_CURRENT_ADC_DIV_ROUND_UP(a, b) (((a) + (b) - 1u) / (b))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
volatile stc_GPIO_PRT_t *gpioPort;
|
||||
uint32_t gpioPin;
|
||||
en_hsiom_sel_t gpioHsiom;
|
||||
volatile stc_PASS_SAR_CH_t *adcChannel;
|
||||
cy_en_adc_pin_address_t pinAddress;
|
||||
} bsp_seat_current_adc_profile_t;
|
||||
|
||||
static const bsp_seat_current_adc_profile_t s_profiles[] =
|
||||
{
|
||||
{
|
||||
SEAT_CURRENT_M0_PORT,
|
||||
SEAT_CURRENT_M0_PIN,
|
||||
SEAT_CURRENT_M0_GPIO_HSIOM,
|
||||
SEAT_CURRENT_M0_CHANNEL,
|
||||
SEAT_CURRENT_M0_PIN_ADDRESS,
|
||||
},
|
||||
{
|
||||
SEAT_CURRENT_M1_PORT,
|
||||
SEAT_CURRENT_M1_PIN,
|
||||
SEAT_CURRENT_M1_GPIO_HSIOM,
|
||||
SEAT_CURRENT_M1_CHANNEL,
|
||||
SEAT_CURRENT_M1_PIN_ADDRESS,
|
||||
},
|
||||
{
|
||||
SEAT_CURRENT_M2_PORT,
|
||||
SEAT_CURRENT_M2_PIN,
|
||||
SEAT_CURRENT_M2_GPIO_HSIOM,
|
||||
SEAT_CURRENT_M2_CHANNEL,
|
||||
SEAT_CURRENT_M2_PIN_ADDRESS,
|
||||
},
|
||||
{
|
||||
SEAT_CURRENT_M3_PORT,
|
||||
SEAT_CURRENT_M3_PIN,
|
||||
SEAT_CURRENT_M3_GPIO_HSIOM,
|
||||
SEAT_CURRENT_M3_CHANNEL,
|
||||
SEAT_CURRENT_M3_PIN_ADDRESS,
|
||||
},
|
||||
{
|
||||
SEAT_CURRENT_HEATER_PORT,
|
||||
SEAT_CURRENT_HEATER_PIN,
|
||||
SEAT_CURRENT_HEATER_GPIO_HSIOM,
|
||||
SEAT_CURRENT_HEATER_CHANNEL,
|
||||
SEAT_CURRENT_HEATER_PIN_ADDRESS,
|
||||
},
|
||||
{
|
||||
SEAT_CURRENT_FAN_PORT,
|
||||
SEAT_CURRENT_FAN_PIN,
|
||||
SEAT_CURRENT_FAN_GPIO_HSIOM,
|
||||
SEAT_CURRENT_FAN_CHANNEL,
|
||||
SEAT_CURRENT_FAN_PIN_ADDRESS,
|
||||
},
|
||||
};
|
||||
|
||||
typedef char bsp_seat_current_adc_profile_count_must_match[
|
||||
((sizeof(s_profiles) / sizeof(s_profiles[0])) ==
|
||||
(uint32_t)BSP_SEAT_CURRENT_ADC_SIGNAL_COUNT) ? 1 : -1];
|
||||
|
||||
static bool s_initialized = false;
|
||||
static bool s_sampleActive = false;
|
||||
static uint16_t s_lastRaw[BSP_SEAT_CURRENT_ADC_SIGNAL_COUNT];
|
||||
static bool s_lastRawValid[BSP_SEAT_CURRENT_ADC_SIGNAL_COUNT];
|
||||
|
||||
static bool BspSeatCurrentAdc_ConfigClock(uint32_t *actualClockHz);
|
||||
static bool BspSeatCurrentAdc_WaitDone(
|
||||
volatile stc_PASS_SAR_CH_t *channel);
|
||||
static void BspSeatCurrentAdc_ClearStatus(
|
||||
volatile stc_PASS_SAR_CH_t *channel);
|
||||
|
||||
bool BspSeatCurrentAdc_Init(void)
|
||||
{
|
||||
uint32_t actualClockHz;
|
||||
uint32_t samplingCycles;
|
||||
uint32_t index;
|
||||
cy_stc_gpio_pin_config_t pinConfig =
|
||||
{
|
||||
.outVal = 0u,
|
||||
.driveMode = CY_GPIO_DM_ANALOG,
|
||||
.hsiom = HSIOM_SEL_GPIO,
|
||||
.intEdge = 0u,
|
||||
.intMask = 0u,
|
||||
.vtrip = 0u,
|
||||
.slewRate = 0u,
|
||||
.driveSel = 0u,
|
||||
};
|
||||
cy_stc_adc_config_t adcConfig =
|
||||
{
|
||||
.preconditionTime = 0u,
|
||||
.powerupTime = 0u,
|
||||
.enableIdlePowerDown = false,
|
||||
.msbStretchMode = CY_ADC_MSB_STRETCH_MODE_1CYCLE,
|
||||
.enableHalfLsbConv = false,
|
||||
.sarMuxEnable = true,
|
||||
.adcEnable = true,
|
||||
.sarIpEnable = true,
|
||||
};
|
||||
cy_stc_adc_channel_config_t channelConfig =
|
||||
{
|
||||
.triggerSelection = CY_ADC_TRIGGER_OFF,
|
||||
.channelPriority = 0u,
|
||||
.preenptionType = CY_ADC_PREEMPTION_FINISH_RESUME,
|
||||
.isGroupEnd = true,
|
||||
.doneLevel = CY_ADC_DONE_LEVEL_PULSE,
|
||||
.pinAddress = CY_ADC_PIN_ADDRESS_AN0,
|
||||
.portAddress = SEAT_CURRENT_ADC_PORT_ADDRESS,
|
||||
.extMuxSelect = 0u,
|
||||
.extMuxEnable = true,
|
||||
.preconditionMode = CY_ADC_PRECONDITION_MODE_OFF,
|
||||
.overlapDiagMode = CY_ADC_OVERLAP_DIAG_MODE_OFF,
|
||||
.sampleTime = 0u,
|
||||
.calibrationValueSelect = CY_ADC_CALIBRATION_VALUE_REGULAR,
|
||||
.postProcessingMode = CY_ADC_POST_PROCESSING_MODE_NONE,
|
||||
.resultAlignment = CY_ADC_RESULT_ALIGNMENT_RIGHT,
|
||||
.signExtention = CY_ADC_SIGN_EXTENTION_UNSIGNED,
|
||||
.averageCount = 0u,
|
||||
.rightShift = 0u,
|
||||
.rangeDetectionMode = CY_ADC_RANGE_DETECTION_MODE_INSIDE_RANGE,
|
||||
.rangeDetectionLoThreshold = 0u,
|
||||
.rangeDetectionHiThreshold = SEAT_CURRENT_ADC_FULL_SCALE,
|
||||
.mask.grpDone = true,
|
||||
.mask.grpCancelled = false,
|
||||
.mask.grpOverflow = false,
|
||||
.mask.chRange = false,
|
||||
.mask.chPulse = false,
|
||||
.mask.chOverflow = false,
|
||||
};
|
||||
|
||||
if(s_initialized)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for(index = 0u;
|
||||
index < (uint32_t)BSP_SEAT_CURRENT_ADC_SIGNAL_COUNT;
|
||||
index++)
|
||||
{
|
||||
pinConfig.hsiom = s_profiles[index].gpioHsiom;
|
||||
if(Cy_GPIO_Pin_Init(s_profiles[index].gpioPort,
|
||||
s_profiles[index].gpioPin,
|
||||
&pinConfig) != CY_GPIO_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
s_lastRaw[index] = 0u;
|
||||
s_lastRawValid[index] = false;
|
||||
}
|
||||
|
||||
if(!BspSeatCurrentAdc_ConfigClock(&actualClockHz))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
samplingCycles = (uint32_t)SEAT_CURRENT_ADC_DIV_ROUND_UP(
|
||||
(SEAT_CURRENT_ADC_SAMPLE_TIME_MIN_NS * (uint64_t)actualClockHz),
|
||||
1000000000ull);
|
||||
if(samplingCycles == 0u)
|
||||
{
|
||||
samplingCycles = 1u;
|
||||
}
|
||||
channelConfig.sampleTime = (uint16_t)samplingCycles;
|
||||
|
||||
Cy_Adc_DeInit(SEAT_CURRENT_ADC_INSTANCE);
|
||||
if(Cy_Adc_Init(SEAT_CURRENT_ADC_INSTANCE,
|
||||
&adcConfig) != CY_ADC_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for(index = 0u;
|
||||
index < (uint32_t)BSP_SEAT_CURRENT_ADC_SIGNAL_COUNT;
|
||||
index++)
|
||||
{
|
||||
channelConfig.pinAddress = s_profiles[index].pinAddress;
|
||||
if(Cy_Adc_Channel_Init(s_profiles[index].adcChannel,
|
||||
&channelConfig) != CY_ADC_SUCCESS)
|
||||
{
|
||||
Cy_Adc_DeInit(SEAT_CURRENT_ADC_INSTANCE);
|
||||
return false;
|
||||
}
|
||||
Cy_Adc_Channel_Enable(s_profiles[index].adcChannel);
|
||||
}
|
||||
|
||||
s_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BspSeatCurrentAdc_Sample(bsp_seat_current_adc_signal_t signal,
|
||||
uint16_t *raw)
|
||||
{
|
||||
uint32_t index = (uint32_t)signal;
|
||||
uint16_t sample = 0u;
|
||||
cy_stc_adc_ch_status_t resultStatus = { false };
|
||||
volatile stc_PASS_SAR_CH_t *channel;
|
||||
bool success = false;
|
||||
|
||||
if(!s_initialized || s_sampleActive ||
|
||||
(index >= (uint32_t)BSP_SEAT_CURRENT_ADC_SIGNAL_COUNT))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
s_sampleActive = true;
|
||||
channel = s_profiles[index].adcChannel;
|
||||
BspSeatCurrentAdc_ClearStatus(channel);
|
||||
Cy_Adc_Channel_SoftwareTrigger(channel);
|
||||
if(BspSeatCurrentAdc_WaitDone(channel) &&
|
||||
(Cy_Adc_Channel_GetResult(channel,
|
||||
&sample,
|
||||
&resultStatus) == CY_ADC_SUCCESS) &&
|
||||
resultStatus.valid)
|
||||
{
|
||||
sample = (uint16_t)(sample & SEAT_CURRENT_ADC_FULL_SCALE);
|
||||
s_lastRaw[index] = sample;
|
||||
s_lastRawValid[index] = true;
|
||||
if(raw != NULL)
|
||||
{
|
||||
*raw = sample;
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
BspSeatCurrentAdc_ClearStatus(channel);
|
||||
s_sampleActive = false;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool BspSeatCurrentAdc_GetLastRaw(bsp_seat_current_adc_signal_t signal,
|
||||
uint16_t *raw)
|
||||
{
|
||||
uint32_t index = (uint32_t)signal;
|
||||
|
||||
if((raw == NULL) ||
|
||||
(index >= (uint32_t)BSP_SEAT_CURRENT_ADC_SIGNAL_COUNT) ||
|
||||
!s_lastRawValid[index])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*raw = s_lastRaw[index];
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool BspSeatCurrentAdc_ConfigClock(uint32_t *actualClockHz)
|
||||
{
|
||||
uint32_t periClockHz = 0u;
|
||||
uint32_t divider;
|
||||
uint32_t clockGroup = Cy_SysClk_GetClockGroup(SEAT_CURRENT_ADC_PCLK);
|
||||
|
||||
if((actualClockHz == NULL) ||
|
||||
(Cy_SysClk_GetClkPeriFrequency(&periClockHz) != CY_SYSCLK_SUCCESS))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
divider = SEAT_CURRENT_ADC_DIV_ROUND_UP(
|
||||
periClockHz, SEAT_CURRENT_ADC_OPERATION_FREQ_MAX_HZ);
|
||||
if((divider == 0u) || (divider > 65536u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_SysClk_PeriphDisableDivider(
|
||||
clockGroup,
|
||||
CY_SYSCLK_DIV_16_BIT,
|
||||
SEAT_CURRENT_ADC_DIVIDER_NUMBER) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_SysClk_PeriphAssignDivider(
|
||||
SEAT_CURRENT_ADC_PCLK,
|
||||
CY_SYSCLK_DIV_16_BIT,
|
||||
SEAT_CURRENT_ADC_DIVIDER_NUMBER) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_SysClk_PeriphSetDivider(
|
||||
clockGroup,
|
||||
CY_SYSCLK_DIV_16_BIT,
|
||||
SEAT_CURRENT_ADC_DIVIDER_NUMBER,
|
||||
divider - 1u) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_SysClk_PeriphEnableDivider(
|
||||
clockGroup,
|
||||
CY_SYSCLK_DIV_16_BIT,
|
||||
SEAT_CURRENT_ADC_DIVIDER_NUMBER) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*actualClockHz = periClockHz / divider;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool BspSeatCurrentAdc_WaitDone(
|
||||
volatile stc_PASS_SAR_CH_t *channel)
|
||||
{
|
||||
uint32_t timeout = SEAT_CURRENT_ADC_POLL_TIMEOUT;
|
||||
cy_stc_adc_interrupt_source_t status = { false };
|
||||
|
||||
do
|
||||
{
|
||||
(void)Cy_Adc_Channel_GetInterruptStatus(channel, &status);
|
||||
if(status.grpDone)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
timeout--;
|
||||
} while(timeout > 0u);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void BspSeatCurrentAdc_ClearStatus(
|
||||
volatile stc_PASS_SAR_CH_t *channel)
|
||||
{
|
||||
cy_stc_adc_interrupt_source_t clearSource =
|
||||
{
|
||||
.grpDone = true,
|
||||
.grpCancelled = true,
|
||||
.grpOverflow = true,
|
||||
.chRange = false,
|
||||
.chPulse = false,
|
||||
.chOverflow = true,
|
||||
};
|
||||
|
||||
(void)Cy_Adc_Channel_ClearInterruptStatus(channel, &clearSource);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef BSP_SEAT_CURRENT_ADC_H
|
||||
#define BSP_SEAT_CURRENT_ADC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BSP_SEAT_CURRENT_ADC_MOTOR0 = 0,
|
||||
BSP_SEAT_CURRENT_ADC_MOTOR1,
|
||||
BSP_SEAT_CURRENT_ADC_MOTOR2,
|
||||
BSP_SEAT_CURRENT_ADC_MOTOR3,
|
||||
BSP_SEAT_CURRENT_ADC_HEATER,
|
||||
BSP_SEAT_CURRENT_ADC_FAN,
|
||||
BSP_SEAT_CURRENT_ADC_SIGNAL_COUNT
|
||||
} bsp_seat_current_adc_signal_t;
|
||||
|
||||
/* Initializes PASS0 SAR1 once and enables every shared seat-current channel. */
|
||||
bool BspSeatCurrentAdc_Init(void);
|
||||
|
||||
/* Main-loop polling API. It must not be called from an ISR. */
|
||||
bool BspSeatCurrentAdc_Sample(bsp_seat_current_adc_signal_t signal,
|
||||
uint16_t *raw);
|
||||
bool BspSeatCurrentAdc_GetLastRaw(bsp_seat_current_adc_signal_t signal,
|
||||
uint16_t *raw);
|
||||
|
||||
#endif /* BSP_SEAT_CURRENT_ADC_H */
|
||||
@@ -0,0 +1,659 @@
|
||||
#include "bsp_seat_fan.h"
|
||||
|
||||
#include "cy_project.h"
|
||||
#include "cy_device_headers.h"
|
||||
#include "seat_fan_config.h"
|
||||
|
||||
static bool BspSeatFan_ConfigClock(void);
|
||||
static uint32_t BspSeatFan_DutyToCompare(uint32_t dutyPercent);
|
||||
static void BspSeatFan_SetPinGpioLow(volatile stc_GPIO_PRT_t *port,
|
||||
uint32_t pin,
|
||||
en_hsiom_sel_t gpioHsiom);
|
||||
static bool BspSeatCan_ConfigClock(void);
|
||||
static bool BspSeatCan_ConfigPins(void);
|
||||
static void BspSeatCan_IrqHandler(void);
|
||||
static void BspSeatCan_RxCallback(bool rxFifoMessage,
|
||||
uint8_t rxBufferOrFifo,
|
||||
cy_stc_canfd_msg_t *message);
|
||||
|
||||
volatile uint32_t g_bspSeatCanInitStatus = (uint32_t)CY_CANFD_SUCCESS;
|
||||
volatile uint32_t g_bspSeatCanRxCount = 0u;
|
||||
volatile uint32_t g_bspSeatCanRxQueueOverflowCount = 0u;
|
||||
volatile uint32_t g_bspSeatCanTxCount = 0u;
|
||||
volatile uint32_t g_bspSeatCanTxBusyCount = 0u;
|
||||
volatile uint32_t g_bspSeatCanLastRxId = 0u;
|
||||
volatile uint32_t g_bspSeatCanLastTxId = 0u;
|
||||
volatile uint32_t g_bspSeatCanLastTxStatus = (uint32_t)CY_CANFD_SUCCESS;
|
||||
|
||||
static volatile bsp_seat_can_frame_t s_canRxQueue[SEAT_FAN_CAN_RX_QUEUE_DEPTH];
|
||||
static volatile uint8_t s_canRxQueueHead = 0u;
|
||||
static volatile uint8_t s_canRxQueueTail = 0u;
|
||||
|
||||
volatile uint32_t g_bspSeatFanStartFailStage = 0u;
|
||||
|
||||
static const cy_stc_id_filter_t s_canStandardIdFilters[] =
|
||||
{
|
||||
CANFD_CONFIG_STD_ID_FILTER_RANGE(
|
||||
SEAT_FAN_CAN_CONTROL_29E_ID,
|
||||
SEAT_FAN_CAN_CONTROL_29E_ID,
|
||||
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0),
|
||||
CANFD_CONFIG_STD_ID_FILTER_RANGE(
|
||||
SEAT_FAN_CAN_CONFIG_2AA_ID,
|
||||
SEAT_FAN_CAN_CONFIG_2AA_ID,
|
||||
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0),
|
||||
CANFD_CONFIG_STD_ID_FILTER_RANGE(
|
||||
SEAT_FAN_CAN_SWITCH_42A_ID,
|
||||
SEAT_FAN_CAN_SWITCH_42A_ID,
|
||||
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0),
|
||||
};
|
||||
|
||||
static cy_stc_sysint_irq_t s_canIrqConfig =
|
||||
{
|
||||
.sysIntSrc = SEAT_FAN_CAN_IRQN,
|
||||
.intIdx = SEAT_FAN_CAN_CPU_IRQ,
|
||||
.isEnabled = true,
|
||||
};
|
||||
|
||||
static cy_stc_canfd_config_t s_canConfig =
|
||||
{
|
||||
.txCallback = NULL,
|
||||
.rxCallback = BspSeatCan_RxCallback,
|
||||
.rxFifoWithTopCallback = NULL,
|
||||
.statusCallback = NULL,
|
||||
.errorCallback = NULL,
|
||||
.canFDMode = false,
|
||||
.bitrate =
|
||||
{
|
||||
/* 40 MHz / (10 * (1 + 5 + 2)) = 500 kbit/s. */
|
||||
.prescaler = 10u - 1u,
|
||||
.timeSegment1 = 5u - 1u,
|
||||
.timeSegment2 = 2u - 1u,
|
||||
.syncJumpWidth = 2u - 1u,
|
||||
},
|
||||
.fastBitrate =
|
||||
{
|
||||
.prescaler = 0u,
|
||||
.timeSegment1 = 0u,
|
||||
.timeSegment2 = 0u,
|
||||
.syncJumpWidth = 0u,
|
||||
},
|
||||
.tdcConfig =
|
||||
{
|
||||
.tdcEnabled = false,
|
||||
.tdcOffset = 0u,
|
||||
.tdcFilterWindow = 0u,
|
||||
},
|
||||
.sidFilterConfig =
|
||||
{
|
||||
.numberOfSIDFilters =
|
||||
sizeof(s_canStandardIdFilters) / sizeof(s_canStandardIdFilters[0]),
|
||||
.sidFilter = s_canStandardIdFilters,
|
||||
},
|
||||
.extidFilterConfig =
|
||||
{
|
||||
.numberOfEXTIDFilters = 0u,
|
||||
.extidFilter = NULL,
|
||||
.extIDANDMask = 0x1FFFFFFFu,
|
||||
},
|
||||
.globalFilterConfig =
|
||||
{
|
||||
.nonMatchingFramesStandard = CY_CANFD_REJECT_NON_MATCHING,
|
||||
.nonMatchingFramesExtended = CY_CANFD_REJECT_NON_MATCHING,
|
||||
.rejectRemoteFramesStandard = true,
|
||||
.rejectRemoteFramesExtended = true,
|
||||
},
|
||||
.rxBufferDataSize = CY_CANFD_BUFFER_DATA_SIZE_8,
|
||||
.rxFifo1DataSize = CY_CANFD_BUFFER_DATA_SIZE_8,
|
||||
.rxFifo0DataSize = CY_CANFD_BUFFER_DATA_SIZE_8,
|
||||
.txBufferDataSize = CY_CANFD_BUFFER_DATA_SIZE_8,
|
||||
.rxFifo0Config =
|
||||
{
|
||||
.mode = CY_CANFD_FIFO_MODE_BLOCKING,
|
||||
.watermark = 0u,
|
||||
.numberOfFifoElements = SEAT_FAN_CAN_RX_FIFO0_ELEMENTS,
|
||||
.topPointerLogicEnabled = false,
|
||||
},
|
||||
.rxFifo1Config =
|
||||
{
|
||||
.mode = CY_CANFD_FIFO_MODE_BLOCKING,
|
||||
.watermark = 0u,
|
||||
.numberOfFifoElements = 0u,
|
||||
.topPointerLogicEnabled = false,
|
||||
},
|
||||
.noOfRxBuffers = 0u,
|
||||
.noOfTxBuffers = SEAT_FAN_CAN_TX_BUFFER_COUNT,
|
||||
};
|
||||
|
||||
static const cy_stc_tcpwm_pwm_config_t s_seatFanPwmConfig =
|
||||
{
|
||||
.pwmMode = CY_TCPWM_PWM_MODE_PWM,
|
||||
.clockPrescaler = CY_TCPWM_PRESCALER_DIVBY_1,
|
||||
.debug_pause = false,
|
||||
.deadTime = 0u,
|
||||
.deadTimeComp = 0u,
|
||||
.runMode = CY_TCPWM_PWM_CONTINUOUS,
|
||||
.countDirection = CY_TCPWM_COUNTER_COUNT_UP,
|
||||
.cc0MatchMode = CY_TCPWM_PWM_TR_CTRL2_CLEAR,
|
||||
.overflowMode = CY_TCPWM_PWM_TR_CTRL2_SET,
|
||||
.underflowMode = CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE,
|
||||
.cc1MatchMode = CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE,
|
||||
.period = SEAT_FAN_PWM_PERIOD_TICKS - 1u,
|
||||
.period_buff = 0u,
|
||||
.enablePeriodSwap = false,
|
||||
.enableLineSelSwap = false,
|
||||
.compare0 = SEAT_FAN_PWM_PERIOD_TICKS,
|
||||
.compare0_buff = 0u,
|
||||
.enableCompare0Swap = false,
|
||||
.compare1 = 0u,
|
||||
.compare1_buff = 0u,
|
||||
.enableCompare1Swap = false,
|
||||
.interruptSources = CY_TCPWM_INT_NONE,
|
||||
.invertPWMOut = 0u,
|
||||
.invertPWMOutN = 0u,
|
||||
.killMode = CY_TCPWM_PWM_STOP_ON_KILL,
|
||||
.switchInputMode = CY_TCPWM_INPUT_LEVEL,
|
||||
.switchInput = 0u,
|
||||
.reloadInputMode = CY_TCPWM_INPUT_LEVEL,
|
||||
.reloadInput = 0u,
|
||||
.startInputMode = CY_TCPWM_INPUT_LEVEL,
|
||||
.startInput = 0u,
|
||||
.kill0InputMode = CY_TCPWM_INPUT_LEVEL,
|
||||
.kill0Input = 0u,
|
||||
.kill1InputMode = CY_TCPWM_INPUT_LEVEL,
|
||||
.kill1Input = 0u,
|
||||
.countInputMode = CY_TCPWM_INPUT_LEVEL,
|
||||
.countInput = 1u,
|
||||
.immediateKill = true,
|
||||
.pwmOnDisable = CY_TCPWM_PWM_OUT_MODE_LOW,
|
||||
.trigger0EventCfg = CY_TCPWM_COUNTER_OVERFLOW,
|
||||
.trigger1EventCfg = CY_TCPWM_COUNTER_OVERFLOW,
|
||||
};
|
||||
|
||||
bool BspSeatFan_ForceOff(void)
|
||||
{
|
||||
cy_stc_gpio_pin_config_t pinConfig =
|
||||
{
|
||||
.outVal = 0u,
|
||||
.driveMode = CY_GPIO_DM_STRONG_IN_OFF,
|
||||
.hsiom = SEAT_FAN_PWM_GPIO_HSIOM,
|
||||
.intEdge = 0u,
|
||||
.intMask = 0u,
|
||||
.vtrip = 0u,
|
||||
.slewRate = 0u,
|
||||
.driveSel = CY_GPIO_DRIVE_FULL,
|
||||
};
|
||||
cy_en_gpio_status_t pwmPinStatus;
|
||||
cy_en_gpio_status_t unusedPinStatus;
|
||||
|
||||
pwmPinStatus = Cy_GPIO_Pin_Init(SEAT_FAN_PWM_PORT,
|
||||
SEAT_FAN_PWM_PIN,
|
||||
&pinConfig);
|
||||
|
||||
pinConfig.hsiom = SEAT_FAN_UNUSED_GPIO_HSIOM;
|
||||
unusedPinStatus = Cy_GPIO_Pin_Init(SEAT_FAN_UNUSED_PORT,
|
||||
SEAT_FAN_UNUSED_PIN,
|
||||
&pinConfig);
|
||||
|
||||
/* Write the output latches again after configuration for an explicit safe state. */
|
||||
Cy_GPIO_Write(SEAT_FAN_PWM_PORT, SEAT_FAN_PWM_PIN, 0u);
|
||||
Cy_GPIO_Write(SEAT_FAN_UNUSED_PORT, SEAT_FAN_UNUSED_PIN, 0u);
|
||||
|
||||
return ((pwmPinStatus == CY_GPIO_SUCCESS) &&
|
||||
(unusedPinStatus == CY_GPIO_SUCCESS));
|
||||
}
|
||||
|
||||
bool BspSeatFan_InitPwm(void)
|
||||
{
|
||||
if(!BspSeatFan_ConfigClock())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Cy_Tcpwm_Pwm_Disable(SEAT_FAN_PWM_TCPWM);
|
||||
|
||||
if(Cy_Tcpwm_Pwm_Init(SEAT_FAN_PWM_TCPWM,
|
||||
&s_seatFanPwmConfig) != CY_RET_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((Cy_Tcpwm_Pwm_GetPeriod(SEAT_FAN_PWM_TCPWM) ==
|
||||
(SEAT_FAN_PWM_PERIOD_TICKS - 1u)) &&
|
||||
(Cy_Tcpwm_Pwm_GetCompare0(SEAT_FAN_PWM_TCPWM) ==
|
||||
SEAT_FAN_PWM_PERIOD_TICKS));
|
||||
}
|
||||
|
||||
bool BspSeatFan_Start(uint32_t dutyPercent)
|
||||
{
|
||||
g_bspSeatFanStartFailStage = 0u;
|
||||
if(!BspSeatFan_SetDutyPercent(dutyPercent))
|
||||
{
|
||||
g_bspSeatFanStartFailStage = 1u;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* P11.1 is still GPIO low here. Starting from PERIOD makes the first
|
||||
* counter clock generate overflow immediately, which asserts LINE high
|
||||
* for the 100% startup setting before the pin is switched to TCPWM.
|
||||
*/
|
||||
Cy_GPIO_Write(SEAT_FAN_PWM_PORT, SEAT_FAN_PWM_PIN, 0u);
|
||||
Cy_Tcpwm_Pwm_SetCounter(SEAT_FAN_PWM_TCPWM,
|
||||
SEAT_FAN_PWM_PERIOD_TICKS - 1u);
|
||||
Cy_Tcpwm_Pwm_Enable(SEAT_FAN_PWM_TCPWM);
|
||||
Cy_Tcpwm_TriggerStart(SEAT_FAN_PWM_TCPWM);
|
||||
|
||||
/* Keep the pin at GPIO low until the 2 MHz counter has started and overflowed. */
|
||||
Cy_SysTick_DelayInUs(2u);
|
||||
if((Cy_Tcpwm_Pwm_GetStatus(SEAT_FAN_PWM_TCPWM) &
|
||||
TCPWM_GRP_CNT_STATUS_RUNNING_Msk) == 0u)
|
||||
{
|
||||
g_bspSeatFanStartFailStage = 2u;
|
||||
BspSeatFan_FailSafeOff();
|
||||
return false;
|
||||
}
|
||||
|
||||
Cy_GPIO_SetDriveSel(SEAT_FAN_PWM_PORT,
|
||||
SEAT_FAN_PWM_PIN,
|
||||
CY_GPIO_DRIVE_FULL);
|
||||
Cy_GPIO_SetDrivemode(SEAT_FAN_PWM_PORT,
|
||||
SEAT_FAN_PWM_PIN,
|
||||
CY_GPIO_DM_STRONG_IN_OFF);
|
||||
Cy_GPIO_SetHSIOM(SEAT_FAN_PWM_PORT,
|
||||
SEAT_FAN_PWM_PIN,
|
||||
SEAT_FAN_PWM_HSIOM);
|
||||
|
||||
if(Cy_GPIO_GetHSIOM(SEAT_FAN_PWM_PORT,
|
||||
SEAT_FAN_PWM_PIN) != SEAT_FAN_PWM_HSIOM)
|
||||
{
|
||||
g_bspSeatFanStartFailStage = 3u;
|
||||
BspSeatFan_FailSafeOff();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BspSeatFan_SetDutyPercent(uint32_t dutyPercent)
|
||||
{
|
||||
uint32_t compare;
|
||||
|
||||
if(dutyPercent > 100u)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
compare = BspSeatFan_DutyToCompare(dutyPercent);
|
||||
Cy_Tcpwm_Pwm_SetCompare0(SEAT_FAN_PWM_TCPWM, compare);
|
||||
|
||||
return (Cy_Tcpwm_Pwm_GetCompare0(SEAT_FAN_PWM_TCPWM) == compare);
|
||||
}
|
||||
|
||||
void BspSeatFan_FailSafeOff(void)
|
||||
{
|
||||
Cy_Tcpwm_Pwm_Disable(SEAT_FAN_PWM_TCPWM);
|
||||
|
||||
BspSeatFan_SetPinGpioLow(SEAT_FAN_PWM_PORT,
|
||||
SEAT_FAN_PWM_PIN,
|
||||
SEAT_FAN_PWM_GPIO_HSIOM);
|
||||
BspSeatFan_SetPinGpioLow(SEAT_FAN_UNUSED_PORT,
|
||||
SEAT_FAN_UNUSED_PIN,
|
||||
SEAT_FAN_UNUSED_GPIO_HSIOM);
|
||||
}
|
||||
|
||||
bool BspSeatCan_Init(void)
|
||||
{
|
||||
cy_en_canfd_status_t canStatus;
|
||||
|
||||
if(!BspSeatCan_ConfigClock() || !BspSeatCan_ConfigPins())
|
||||
{
|
||||
g_bspSeatCanInitStatus = (uint32_t)CY_CANFD_BAD_PARAM;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Cy_SysInt_InitIRQ(&s_canIrqConfig) != CY_SYSINT_SUCCESS)
|
||||
{
|
||||
g_bspSeatCanInitStatus = (uint32_t)CY_CANFD_BAD_PARAM;
|
||||
return false;
|
||||
}
|
||||
|
||||
Cy_SysInt_SetSystemIrqVector(s_canIrqConfig.sysIntSrc,
|
||||
BspSeatCan_IrqHandler);
|
||||
NVIC_SetPriority(s_canIrqConfig.intIdx, 0u);
|
||||
NVIC_ClearPendingIRQ(s_canIrqConfig.intIdx);
|
||||
|
||||
(void)Cy_CANFD_DeInit(SEAT_FAN_CAN_TYPE);
|
||||
canStatus = Cy_CANFD_Init(SEAT_FAN_CAN_TYPE, &s_canConfig);
|
||||
g_bspSeatCanInitStatus = (uint32_t)canStatus;
|
||||
if(canStatus != CY_CANFD_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
NVIC_EnableIRQ(s_canIrqConfig.intIdx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BspSeatCan_Read(bsp_seat_can_frame_t *frame)
|
||||
{
|
||||
uint32_t interruptState;
|
||||
uint8_t tail;
|
||||
|
||||
if(frame == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
interruptState = Cy_SysLib_EnterCriticalSection();
|
||||
tail = s_canRxQueueTail;
|
||||
if(tail == s_canRxQueueHead)
|
||||
{
|
||||
Cy_SysLib_ExitCriticalSection(interruptState);
|
||||
return false;
|
||||
}
|
||||
|
||||
frame->identifier = s_canRxQueue[tail].identifier;
|
||||
frame->data0 = s_canRxQueue[tail].data0;
|
||||
frame->data1 = s_canRxQueue[tail].data1;
|
||||
frame->dlc = s_canRxQueue[tail].dlc;
|
||||
|
||||
tail++;
|
||||
if(tail >= SEAT_FAN_CAN_RX_QUEUE_DEPTH)
|
||||
{
|
||||
tail = 0u;
|
||||
}
|
||||
s_canRxQueueTail = tail;
|
||||
Cy_SysLib_ExitCriticalSection(interruptState);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BspSeatCan_Send(uint32_t identifier, uint32_t data0, uint32_t data1)
|
||||
{
|
||||
cy_stc_canfd_msg_t message;
|
||||
uint8_t bufferIndex;
|
||||
uint8_t dataIndex;
|
||||
|
||||
if(identifier > 0x7FFu)
|
||||
{
|
||||
g_bspSeatCanLastTxStatus = (uint32_t)CY_CANFD_BAD_PARAM;
|
||||
return false;
|
||||
}
|
||||
|
||||
message.canFDFormat = false;
|
||||
message.idConfig.extended = false;
|
||||
message.idConfig.identifier = identifier;
|
||||
message.dataConfig.dataLengthCode = SEAT_FAN_CAN_DLC;
|
||||
message.dataConfig.data[0] = data0;
|
||||
message.dataConfig.data[1] = data1;
|
||||
for(dataIndex = 2u;
|
||||
dataIndex < CY_CANFD_MESSAGE_DATA_BUFFER_SIZE;
|
||||
dataIndex++)
|
||||
{
|
||||
message.dataConfig.data[dataIndex] = 0u;
|
||||
}
|
||||
|
||||
for(bufferIndex = 0u;
|
||||
bufferIndex < SEAT_FAN_CAN_TX_BUFFER_COUNT;
|
||||
bufferIndex++)
|
||||
{
|
||||
cy_en_canfd_tx_buffer_status_t bufferStatus =
|
||||
Cy_CANFD_GetTxBufferStatus(SEAT_FAN_CAN_TYPE, bufferIndex);
|
||||
|
||||
if((bufferStatus != CY_CANFD_TX_BUFFER_PENDING) &&
|
||||
(bufferStatus != CY_CANFD_TX_BUFFER_CANCEL_REQUESTED))
|
||||
{
|
||||
cy_en_canfd_status_t sendStatus;
|
||||
|
||||
g_bspSeatCanLastTxId = identifier;
|
||||
sendStatus = Cy_CANFD_UpdateAndTransmitMsgBuffer(
|
||||
SEAT_FAN_CAN_TYPE,
|
||||
bufferIndex,
|
||||
&message);
|
||||
g_bspSeatCanLastTxStatus = (uint32_t)sendStatus;
|
||||
if(sendStatus == CY_CANFD_SUCCESS)
|
||||
{
|
||||
g_bspSeatCanTxCount++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
g_bspSeatCanTxBusyCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool BspSeatCan_ConfigClock(void)
|
||||
{
|
||||
uint32_t periClockHz = 0u;
|
||||
uint32_t divider;
|
||||
uint32_t clockGroup;
|
||||
|
||||
if(Cy_SysClk_GetClkPeriFrequency(&periClockHz) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if((periClockHz < SEAT_FAN_CAN_CLOCK_HZ) ||
|
||||
((periClockHz % SEAT_FAN_CAN_CLOCK_HZ) != 0u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
divider = periClockHz / SEAT_FAN_CAN_CLOCK_HZ;
|
||||
if((divider == 0u) || (divider > 256u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
clockGroup = Cy_SysClk_GetClockGroup(SEAT_FAN_CAN_PCLK);
|
||||
if(Cy_SysClk_PeriphDisableDivider(clockGroup,
|
||||
CY_SYSCLK_DIV_8_BIT,
|
||||
SEAT_FAN_CAN_DIVIDER_NUMBER) !=
|
||||
CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Cy_SysClk_PeriphAssignDivider(SEAT_FAN_CAN_PCLK,
|
||||
CY_SYSCLK_DIV_8_BIT,
|
||||
SEAT_FAN_CAN_DIVIDER_NUMBER) !=
|
||||
CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Cy_SysClk_PeriphSetDivider(clockGroup,
|
||||
CY_SYSCLK_DIV_8_BIT,
|
||||
SEAT_FAN_CAN_DIVIDER_NUMBER,
|
||||
divider - 1u) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Cy_SysClk_PeriphEnableDivider(clockGroup,
|
||||
CY_SYSCLK_DIV_8_BIT,
|
||||
SEAT_FAN_CAN_DIVIDER_NUMBER) ==
|
||||
CY_SYSCLK_SUCCESS);
|
||||
}
|
||||
|
||||
static bool BspSeatCan_ConfigPins(void)
|
||||
{
|
||||
cy_stc_gpio_pin_config_t rxConfig =
|
||||
{
|
||||
.outVal = 0u,
|
||||
.driveMode = CY_GPIO_DM_HIGHZ,
|
||||
.hsiom = SEAT_FAN_CAN_RX_MUX,
|
||||
.intEdge = 0u,
|
||||
.intMask = 0u,
|
||||
.vtrip = 0u,
|
||||
.slewRate = 0u,
|
||||
.driveSel = 0u,
|
||||
};
|
||||
cy_stc_gpio_pin_config_t txConfig =
|
||||
{
|
||||
.outVal = 1u,
|
||||
.driveMode = CY_GPIO_DM_STRONG,
|
||||
.hsiom = SEAT_FAN_CAN_TX_MUX,
|
||||
.intEdge = 0u,
|
||||
.intMask = 0u,
|
||||
.vtrip = 0u,
|
||||
.slewRate = 0u,
|
||||
.driveSel = 0u,
|
||||
};
|
||||
cy_stc_gpio_pin_config_t transceiverConfig =
|
||||
{
|
||||
.outVal = SEAT_FAN_CAN_TRANSCEIVER_ENABLE,
|
||||
.driveMode = CY_GPIO_DM_STRONG_IN_OFF,
|
||||
.hsiom = SEAT_FAN_CAN_TRANSCEIVER_GPIO_HSIOM,
|
||||
.intEdge = 0u,
|
||||
.intMask = 0u,
|
||||
.vtrip = 0u,
|
||||
.slewRate = 0u,
|
||||
.driveSel = CY_GPIO_DRIVE_FULL,
|
||||
};
|
||||
|
||||
if(Cy_GPIO_Pin_Init(SEAT_FAN_CAN_RX_PORT,
|
||||
SEAT_FAN_CAN_RX_PIN,
|
||||
&rxConfig) != CY_GPIO_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_GPIO_Pin_Init(SEAT_FAN_CAN_TX_PORT,
|
||||
SEAT_FAN_CAN_TX_PIN,
|
||||
&txConfig) != CY_GPIO_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_GPIO_Pin_Init(SEAT_FAN_CAN_TRANSCEIVER_PORT,
|
||||
SEAT_FAN_CAN_TRANSCEIVER_PIN,
|
||||
&transceiverConfig) != CY_GPIO_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Cy_GPIO_Write(SEAT_FAN_CAN_TRANSCEIVER_PORT,
|
||||
SEAT_FAN_CAN_TRANSCEIVER_PIN,
|
||||
SEAT_FAN_CAN_TRANSCEIVER_ENABLE);
|
||||
Cy_SysTick_DelayInUs(1000u);
|
||||
|
||||
return (Cy_GPIO_ReadOut(SEAT_FAN_CAN_TRANSCEIVER_PORT,
|
||||
SEAT_FAN_CAN_TRANSCEIVER_PIN) ==
|
||||
SEAT_FAN_CAN_TRANSCEIVER_ENABLE);
|
||||
}
|
||||
|
||||
static void BspSeatCan_IrqHandler(void)
|
||||
{
|
||||
Cy_CANFD_IrqHandler(SEAT_FAN_CAN_TYPE);
|
||||
}
|
||||
|
||||
static void BspSeatCan_RxCallback(bool rxFifoMessage,
|
||||
uint8_t rxBufferOrFifo,
|
||||
cy_stc_canfd_msg_t *message)
|
||||
{
|
||||
uint8_t head;
|
||||
uint8_t nextHead;
|
||||
|
||||
(void)rxFifoMessage;
|
||||
(void)rxBufferOrFifo;
|
||||
|
||||
if((message == NULL) || message->idConfig.extended || message->canFDFormat)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_bspSeatCanRxCount++;
|
||||
g_bspSeatCanLastRxId = message->idConfig.identifier;
|
||||
|
||||
head = s_canRxQueueHead;
|
||||
nextHead = head + 1u;
|
||||
if(nextHead >= SEAT_FAN_CAN_RX_QUEUE_DEPTH)
|
||||
{
|
||||
nextHead = 0u;
|
||||
}
|
||||
|
||||
if(nextHead == s_canRxQueueTail)
|
||||
{
|
||||
g_bspSeatCanRxQueueOverflowCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
s_canRxQueue[head].identifier = message->idConfig.identifier;
|
||||
s_canRxQueue[head].dlc = message->dataConfig.dataLengthCode;
|
||||
s_canRxQueue[head].data0 = message->dataConfig.data[0];
|
||||
s_canRxQueue[head].data1 = message->dataConfig.data[1];
|
||||
s_canRxQueueHead = nextHead;
|
||||
}
|
||||
|
||||
static bool BspSeatFan_ConfigClock(void)
|
||||
{
|
||||
uint32_t periClockHz = 0u;
|
||||
uint32_t divider;
|
||||
uint32_t clockGroup;
|
||||
|
||||
if(Cy_SysClk_GetClkPeriFrequency(&periClockHz) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if((periClockHz < SEAT_FAN_COUNTER_CLOCK_HZ) ||
|
||||
((periClockHz % SEAT_FAN_COUNTER_CLOCK_HZ) != 0u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
divider = periClockHz / SEAT_FAN_COUNTER_CLOCK_HZ;
|
||||
if((divider == 0u) || (divider > 65536u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
clockGroup = Cy_SysClk_GetClockGroup(SEAT_FAN_PWM_PCLK);
|
||||
|
||||
if(Cy_SysClk_PeriphDisableDivider(clockGroup,
|
||||
CY_SYSCLK_DIV_16_BIT,
|
||||
SEAT_FAN_PWM_DIVIDER_NUMBER) !=
|
||||
CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Cy_SysClk_PeriphAssignDivider(SEAT_FAN_PWM_PCLK,
|
||||
CY_SYSCLK_DIV_16_BIT,
|
||||
SEAT_FAN_PWM_DIVIDER_NUMBER) !=
|
||||
CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Cy_SysClk_PeriphSetDivider(clockGroup,
|
||||
CY_SYSCLK_DIV_16_BIT,
|
||||
SEAT_FAN_PWM_DIVIDER_NUMBER,
|
||||
divider - 1u) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Cy_SysClk_PeriphEnableDivider(clockGroup,
|
||||
CY_SYSCLK_DIV_16_BIT,
|
||||
SEAT_FAN_PWM_DIVIDER_NUMBER) ==
|
||||
CY_SYSCLK_SUCCESS);
|
||||
}
|
||||
|
||||
static uint32_t BspSeatFan_DutyToCompare(uint32_t dutyPercent)
|
||||
{
|
||||
return (SEAT_FAN_PWM_PERIOD_TICKS * dutyPercent) / 100u;
|
||||
}
|
||||
|
||||
static void BspSeatFan_SetPinGpioLow(volatile stc_GPIO_PRT_t *port,
|
||||
uint32_t pin,
|
||||
en_hsiom_sel_t gpioHsiom)
|
||||
{
|
||||
/* Set the latch low before changing HSIOM to avoid a transient high. */
|
||||
Cy_GPIO_Write(port, pin, 0u);
|
||||
Cy_GPIO_SetHSIOM(port, pin, gpioHsiom);
|
||||
Cy_GPIO_SetDriveSel(port, pin, CY_GPIO_DRIVE_FULL);
|
||||
Cy_GPIO_SetDrivemode(port, pin, CY_GPIO_DM_STRONG_IN_OFF);
|
||||
Cy_GPIO_Write(port, pin, 0u);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifndef BSP_SEAT_FAN_H
|
||||
#define BSP_SEAT_FAN_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t identifier;
|
||||
uint32_t data0;
|
||||
uint32_t data1;
|
||||
uint8_t dlc;
|
||||
} bsp_seat_can_frame_t;
|
||||
|
||||
/* Configure P11.1 and P11.2 as strong GPIO outputs at logic low. */
|
||||
bool BspSeatFan_ForceOff(void);
|
||||
|
||||
/* Configure the peripheral clock and PWM0-60 while P11.1 remains GPIO low. */
|
||||
bool BspSeatFan_InitPwm(void);
|
||||
|
||||
/* Start PWM and only then connect P11.1 to the TCPWM line output. */
|
||||
bool BspSeatFan_Start(uint32_t dutyPercent);
|
||||
|
||||
/* Change the active PWM compare value. Valid range is 0 through 100 percent. */
|
||||
bool BspSeatFan_SetDutyPercent(uint32_t dutyPercent);
|
||||
|
||||
/* Disable TCPWM and restore both known fan-control pins to GPIO low. */
|
||||
void BspSeatFan_FailSafeOff(void);
|
||||
|
||||
/* Read-only HIL diagnostic: 0=none, 1=compare, 2=counter, 3=HSIOM. */
|
||||
extern volatile uint32_t g_bspSeatFanStartFailStage;
|
||||
|
||||
/* Initialize the proven CAN4/TJA1044 board interface at 500 kbit/s. */
|
||||
bool BspSeatCan_Init(void);
|
||||
|
||||
/* Pop one received standard Classic CAN frame from the interrupt-safe queue. */
|
||||
bool BspSeatCan_Read(bsp_seat_can_frame_t *frame);
|
||||
|
||||
/* Send one 8-byte standard Classic CAN frame. */
|
||||
bool BspSeatCan_Send(uint32_t identifier, uint32_t data0, uint32_t data1);
|
||||
|
||||
/* Watch-window diagnostics for hardware integration. */
|
||||
extern volatile uint32_t g_bspSeatCanInitStatus;
|
||||
extern volatile uint32_t g_bspSeatCanRxCount;
|
||||
extern volatile uint32_t g_bspSeatCanRxQueueOverflowCount;
|
||||
extern volatile uint32_t g_bspSeatCanTxCount;
|
||||
extern volatile uint32_t g_bspSeatCanTxBusyCount;
|
||||
extern volatile uint32_t g_bspSeatCanLastRxId;
|
||||
extern volatile uint32_t g_bspSeatCanLastTxId;
|
||||
extern volatile uint32_t g_bspSeatCanLastTxStatus;
|
||||
|
||||
#endif /* BSP_SEAT_FAN_H */
|
||||
@@ -0,0 +1,400 @@
|
||||
#include "bsp_seat_move_can.h"
|
||||
|
||||
#include "cy_project.h"
|
||||
#include "cy_device_headers.h"
|
||||
#include "motor_control.h"
|
||||
#include "seat_move_config.h"
|
||||
|
||||
static bool BspSeatMoveCan_ConfigClock(void);
|
||||
static bool BspSeatMoveCan_ConfigPins(void);
|
||||
static void BspSeatMoveCan_IrqHandler(void);
|
||||
static void BspSeatMoveCan_RxCallback(bool rxFifoMessage,
|
||||
uint8_t rxBufferOrFifo,
|
||||
cy_stc_canfd_msg_t *message);
|
||||
static void BspSeatMoveCan_ErrorCallback(cy_en_canfd_bus_error_t error);
|
||||
|
||||
volatile uint32_t g_bspSeatMoveCanInitStatus = (uint32_t)CY_CANFD_SUCCESS;
|
||||
volatile uint32_t g_bspSeatMoveCanRxCount = 0u;
|
||||
volatile uint32_t g_bspSeatMoveCanRxQueueOverflowCount = 0u;
|
||||
volatile uint32_t g_bspSeatMoveCanTxCount = 0u;
|
||||
volatile uint32_t g_bspSeatMoveCanTxBusyCount = 0u;
|
||||
volatile uint32_t g_bspSeatMoveCanLastRxId = 0u;
|
||||
volatile uint32_t g_bspSeatMoveCanLastTxId = 0u;
|
||||
volatile uint32_t g_bspSeatMoveCanLastTxStatus = (uint32_t)CY_CANFD_SUCCESS;
|
||||
volatile uint32_t g_bspSeatMoveCanBusOff = 0u;
|
||||
|
||||
static volatile bsp_seat_move_can_frame_t
|
||||
s_rxQueue[SEAT_MOVE_CAN_RX_QUEUE_DEPTH];
|
||||
static volatile uint8_t s_rxQueueHead = 0u;
|
||||
static volatile uint8_t s_rxQueueTail = 0u;
|
||||
|
||||
static const cy_stc_id_filter_t s_standardIdFilters[] =
|
||||
{
|
||||
CANFD_CONFIG_STD_ID_FILTER_RANGE(
|
||||
SEAT_MOVE_CAN_COMMAND_ID,
|
||||
SEAT_MOVE_CAN_COMMAND_ID,
|
||||
CY_CANFD_ID_FILTER_ELEMNT_CONFIG_STORE_RXFIFO0),
|
||||
};
|
||||
|
||||
static cy_stc_sysint_irq_t s_canIrqConfig =
|
||||
{
|
||||
.sysIntSrc = SEAT_MOVE_CAN_IRQN,
|
||||
.intIdx = SEAT_MOVE_CAN_CPU_IRQ,
|
||||
.isEnabled = true,
|
||||
};
|
||||
|
||||
static cy_stc_canfd_config_t s_canConfig =
|
||||
{
|
||||
.txCallback = NULL,
|
||||
.rxCallback = BspSeatMoveCan_RxCallback,
|
||||
.rxFifoWithTopCallback = NULL,
|
||||
.statusCallback = NULL,
|
||||
.errorCallback = BspSeatMoveCan_ErrorCallback,
|
||||
.canFDMode = false,
|
||||
.bitrate =
|
||||
{
|
||||
/* 40 MHz / (10 * (1 + 5 + 2)) = 500 kbit/s. */
|
||||
.prescaler = 10u - 1u,
|
||||
.timeSegment1 = 5u - 1u,
|
||||
.timeSegment2 = 2u - 1u,
|
||||
.syncJumpWidth = 2u - 1u,
|
||||
},
|
||||
.fastBitrate =
|
||||
{
|
||||
.prescaler = 0u,
|
||||
.timeSegment1 = 0u,
|
||||
.timeSegment2 = 0u,
|
||||
.syncJumpWidth = 0u,
|
||||
},
|
||||
.tdcConfig =
|
||||
{
|
||||
.tdcEnabled = false,
|
||||
.tdcOffset = 0u,
|
||||
.tdcFilterWindow = 0u,
|
||||
},
|
||||
.sidFilterConfig =
|
||||
{
|
||||
.numberOfSIDFilters =
|
||||
sizeof(s_standardIdFilters) / sizeof(s_standardIdFilters[0]),
|
||||
.sidFilter = s_standardIdFilters,
|
||||
},
|
||||
.extidFilterConfig =
|
||||
{
|
||||
.numberOfEXTIDFilters = 0u,
|
||||
.extidFilter = NULL,
|
||||
.extIDANDMask = 0x1FFFFFFFu,
|
||||
},
|
||||
.globalFilterConfig =
|
||||
{
|
||||
.nonMatchingFramesStandard = CY_CANFD_REJECT_NON_MATCHING,
|
||||
.nonMatchingFramesExtended = CY_CANFD_REJECT_NON_MATCHING,
|
||||
.rejectRemoteFramesStandard = true,
|
||||
.rejectRemoteFramesExtended = true,
|
||||
},
|
||||
.rxBufferDataSize = CY_CANFD_BUFFER_DATA_SIZE_8,
|
||||
.rxFifo1DataSize = CY_CANFD_BUFFER_DATA_SIZE_8,
|
||||
.rxFifo0DataSize = CY_CANFD_BUFFER_DATA_SIZE_8,
|
||||
.txBufferDataSize = CY_CANFD_BUFFER_DATA_SIZE_8,
|
||||
.rxFifo0Config =
|
||||
{
|
||||
.mode = CY_CANFD_FIFO_MODE_BLOCKING,
|
||||
.watermark = 0u,
|
||||
.numberOfFifoElements = SEAT_MOVE_CAN_RX_FIFO0_ELEMENTS,
|
||||
.topPointerLogicEnabled = false,
|
||||
},
|
||||
.rxFifo1Config =
|
||||
{
|
||||
.mode = CY_CANFD_FIFO_MODE_BLOCKING,
|
||||
.watermark = 0u,
|
||||
.numberOfFifoElements = 0u,
|
||||
.topPointerLogicEnabled = false,
|
||||
},
|
||||
.noOfRxBuffers = 0u,
|
||||
.noOfTxBuffers = SEAT_MOVE_CAN_TX_BUFFER_COUNT,
|
||||
};
|
||||
|
||||
bool BspSeatMoveCan_Init(void)
|
||||
{
|
||||
cy_en_canfd_status_t canStatus;
|
||||
|
||||
s_rxQueueHead = 0u;
|
||||
s_rxQueueTail = 0u;
|
||||
g_bspSeatMoveCanBusOff = 0u;
|
||||
if(!BspSeatMoveCan_ConfigClock() || !BspSeatMoveCan_ConfigPins())
|
||||
{
|
||||
g_bspSeatMoveCanInitStatus = (uint32_t)CY_CANFD_BAD_PARAM;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Cy_SysInt_InitIRQ(&s_canIrqConfig) != CY_SYSINT_SUCCESS)
|
||||
{
|
||||
g_bspSeatMoveCanInitStatus = (uint32_t)CY_CANFD_BAD_PARAM;
|
||||
return false;
|
||||
}
|
||||
Cy_SysInt_SetSystemIrqVector(s_canIrqConfig.sysIntSrc,
|
||||
BspSeatMoveCan_IrqHandler);
|
||||
NVIC_SetPriority(s_canIrqConfig.intIdx, 0u);
|
||||
NVIC_ClearPendingIRQ(s_canIrqConfig.intIdx);
|
||||
|
||||
(void)Cy_CANFD_DeInit(SEAT_MOVE_CAN_TYPE);
|
||||
canStatus = Cy_CANFD_Init(SEAT_MOVE_CAN_TYPE, &s_canConfig);
|
||||
g_bspSeatMoveCanInitStatus = (uint32_t)canStatus;
|
||||
if(canStatus != CY_CANFD_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
NVIC_EnableIRQ(s_canIrqConfig.intIdx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BspSeatMoveCan_Read(bsp_seat_move_can_frame_t *frame)
|
||||
{
|
||||
uint32_t interruptState;
|
||||
uint8_t tail;
|
||||
|
||||
if(frame == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
interruptState = Cy_SysLib_EnterCriticalSection();
|
||||
tail = s_rxQueueTail;
|
||||
if(tail == s_rxQueueHead)
|
||||
{
|
||||
Cy_SysLib_ExitCriticalSection(interruptState);
|
||||
return false;
|
||||
}
|
||||
frame->identifier = s_rxQueue[tail].identifier;
|
||||
frame->data0 = s_rxQueue[tail].data0;
|
||||
frame->data1 = s_rxQueue[tail].data1;
|
||||
frame->dlc = s_rxQueue[tail].dlc;
|
||||
tail++;
|
||||
if(tail >= SEAT_MOVE_CAN_RX_QUEUE_DEPTH)
|
||||
{
|
||||
tail = 0u;
|
||||
}
|
||||
s_rxQueueTail = tail;
|
||||
Cy_SysLib_ExitCriticalSection(interruptState);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BspSeatMoveCan_Send(uint32_t identifier,
|
||||
uint32_t data0,
|
||||
uint32_t data1)
|
||||
{
|
||||
cy_stc_canfd_msg_t message = { 0 };
|
||||
uint8_t bufferIndex;
|
||||
|
||||
if((identifier > 0x7FFu) || (g_bspSeatMoveCanBusOff != 0u))
|
||||
{
|
||||
g_bspSeatMoveCanLastTxStatus = (uint32_t)CY_CANFD_BAD_PARAM;
|
||||
return false;
|
||||
}
|
||||
|
||||
message.canFDFormat = false;
|
||||
message.idConfig.extended = false;
|
||||
message.idConfig.identifier = identifier;
|
||||
message.dataConfig.dataLengthCode = SEAT_MOVE_CAN_DLC;
|
||||
message.dataConfig.data[0] = data0;
|
||||
message.dataConfig.data[1] = data1;
|
||||
|
||||
for(bufferIndex = 0u;
|
||||
bufferIndex < SEAT_MOVE_CAN_TX_BUFFER_COUNT;
|
||||
bufferIndex++)
|
||||
{
|
||||
cy_en_canfd_tx_buffer_status_t bufferStatus =
|
||||
Cy_CANFD_GetTxBufferStatus(SEAT_MOVE_CAN_TYPE, bufferIndex);
|
||||
|
||||
if((bufferStatus != CY_CANFD_TX_BUFFER_PENDING) &&
|
||||
(bufferStatus != CY_CANFD_TX_BUFFER_CANCEL_REQUESTED))
|
||||
{
|
||||
cy_en_canfd_status_t sendStatus;
|
||||
|
||||
g_bspSeatMoveCanLastTxId = identifier;
|
||||
sendStatus = Cy_CANFD_UpdateAndTransmitMsgBuffer(
|
||||
SEAT_MOVE_CAN_TYPE, bufferIndex, &message);
|
||||
g_bspSeatMoveCanLastTxStatus = (uint32_t)sendStatus;
|
||||
if(sendStatus == CY_CANFD_SUCCESS)
|
||||
{
|
||||
g_bspSeatMoveCanTxCount++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
g_bspSeatMoveCanTxBusyCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool BspSeatMoveCan_ConfigClock(void)
|
||||
{
|
||||
uint32_t periClockHz = 0u;
|
||||
uint32_t divider;
|
||||
uint32_t clockGroup;
|
||||
|
||||
if(Cy_SysClk_GetClkPeriFrequency(&periClockHz) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if((periClockHz < SEAT_MOVE_CAN_CLOCK_HZ) ||
|
||||
((periClockHz % SEAT_MOVE_CAN_CLOCK_HZ) != 0u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
divider = periClockHz / SEAT_MOVE_CAN_CLOCK_HZ;
|
||||
if((divider == 0u) || (divider > 256u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
clockGroup = Cy_SysClk_GetClockGroup(SEAT_MOVE_CAN_PCLK);
|
||||
if(Cy_SysClk_PeriphDisableDivider(clockGroup,
|
||||
CY_SYSCLK_DIV_8_BIT,
|
||||
SEAT_MOVE_CAN_DIVIDER_NUMBER) !=
|
||||
CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_SysClk_PeriphAssignDivider(SEAT_MOVE_CAN_PCLK,
|
||||
CY_SYSCLK_DIV_8_BIT,
|
||||
SEAT_MOVE_CAN_DIVIDER_NUMBER) !=
|
||||
CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_SysClk_PeriphSetDivider(clockGroup,
|
||||
CY_SYSCLK_DIV_8_BIT,
|
||||
SEAT_MOVE_CAN_DIVIDER_NUMBER,
|
||||
divider - 1u) != CY_SYSCLK_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return (Cy_SysClk_PeriphEnableDivider(clockGroup,
|
||||
CY_SYSCLK_DIV_8_BIT,
|
||||
SEAT_MOVE_CAN_DIVIDER_NUMBER) ==
|
||||
CY_SYSCLK_SUCCESS);
|
||||
}
|
||||
|
||||
static bool BspSeatMoveCan_ConfigPins(void)
|
||||
{
|
||||
cy_stc_gpio_pin_config_t rxConfig =
|
||||
{
|
||||
.outVal = 0u,
|
||||
.driveMode = CY_GPIO_DM_HIGHZ,
|
||||
.hsiom = SEAT_MOVE_CAN_RX_MUX,
|
||||
.intEdge = 0u,
|
||||
.intMask = 0u,
|
||||
.vtrip = 0u,
|
||||
.slewRate = 0u,
|
||||
.driveSel = 0u,
|
||||
};
|
||||
cy_stc_gpio_pin_config_t txConfig =
|
||||
{
|
||||
.outVal = 1u,
|
||||
.driveMode = CY_GPIO_DM_STRONG,
|
||||
.hsiom = SEAT_MOVE_CAN_TX_MUX,
|
||||
.intEdge = 0u,
|
||||
.intMask = 0u,
|
||||
.vtrip = 0u,
|
||||
.slewRate = 0u,
|
||||
.driveSel = 0u,
|
||||
};
|
||||
cy_stc_gpio_pin_config_t enableConfig =
|
||||
{
|
||||
.outVal = SEAT_MOVE_CAN_TRANSCEIVER_ENABLE,
|
||||
.driveMode = CY_GPIO_DM_STRONG_IN_OFF,
|
||||
.hsiom = SEAT_MOVE_CAN_TRANSCEIVER_GPIO_HSIOM,
|
||||
.intEdge = 0u,
|
||||
.intMask = 0u,
|
||||
.vtrip = 0u,
|
||||
.slewRate = 0u,
|
||||
.driveSel = CY_GPIO_DRIVE_FULL,
|
||||
};
|
||||
|
||||
if(Cy_GPIO_Pin_Init(SEAT_MOVE_CAN_RX_PORT,
|
||||
SEAT_MOVE_CAN_RX_PIN,
|
||||
&rxConfig) != CY_GPIO_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_GPIO_Pin_Init(SEAT_MOVE_CAN_TX_PORT,
|
||||
SEAT_MOVE_CAN_TX_PIN,
|
||||
&txConfig) != CY_GPIO_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(Cy_GPIO_Pin_Init(SEAT_MOVE_CAN_TRANSCEIVER_PORT,
|
||||
SEAT_MOVE_CAN_TRANSCEIVER_PIN,
|
||||
&enableConfig) != CY_GPIO_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Cy_GPIO_Write(SEAT_MOVE_CAN_TRANSCEIVER_PORT,
|
||||
SEAT_MOVE_CAN_TRANSCEIVER_PIN,
|
||||
SEAT_MOVE_CAN_TRANSCEIVER_ENABLE);
|
||||
Cy_SysTick_DelayInUs(1000u);
|
||||
return (Cy_GPIO_ReadOut(SEAT_MOVE_CAN_TRANSCEIVER_PORT,
|
||||
SEAT_MOVE_CAN_TRANSCEIVER_PIN) ==
|
||||
SEAT_MOVE_CAN_TRANSCEIVER_ENABLE);
|
||||
}
|
||||
|
||||
static void BspSeatMoveCan_IrqHandler(void)
|
||||
{
|
||||
Cy_CANFD_IrqHandler(SEAT_MOVE_CAN_TYPE);
|
||||
}
|
||||
|
||||
static void BspSeatMoveCan_RxCallback(bool rxFifoMessage,
|
||||
uint8_t rxBufferOrFifo,
|
||||
cy_stc_canfd_msg_t *message)
|
||||
{
|
||||
uint8_t head;
|
||||
uint8_t nextHead;
|
||||
|
||||
(void)rxFifoMessage;
|
||||
(void)rxBufferOrFifo;
|
||||
if((message == NULL) || message->idConfig.extended || message->canFDFormat)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_bspSeatMoveCanRxCount++;
|
||||
g_bspSeatMoveCanLastRxId = message->idConfig.identifier;
|
||||
if((message->idConfig.identifier == SEAT_MOVE_CAN_COMMAND_ID) &&
|
||||
(message->dataConfig.dataLengthCode == SEAT_MOVE_CAN_DLC) &&
|
||||
(((uint8_t)(message->dataConfig.data[0] & 0xFFu)) == 0x09u) &&
|
||||
(((uint8_t)((message->dataConfig.data[0] >> 8u) & 0xFFu)) == 0x10u) &&
|
||||
(message->dataConfig.data[1] == 0u))
|
||||
{
|
||||
Motor_RequestAbortAllFromIsr(
|
||||
(uint16_t)(message->dataConfig.data[0] >> 16u));
|
||||
}
|
||||
head = s_rxQueueHead;
|
||||
nextHead = head + 1u;
|
||||
if(nextHead >= SEAT_MOVE_CAN_RX_QUEUE_DEPTH)
|
||||
{
|
||||
nextHead = 0u;
|
||||
}
|
||||
if(nextHead == s_rxQueueTail)
|
||||
{
|
||||
g_bspSeatMoveCanRxQueueOverflowCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
s_rxQueue[head].identifier = message->idConfig.identifier;
|
||||
s_rxQueue[head].dlc = message->dataConfig.dataLengthCode;
|
||||
s_rxQueue[head].data0 = message->dataConfig.data[0];
|
||||
s_rxQueue[head].data1 = message->dataConfig.data[1];
|
||||
s_rxQueueHead = nextHead;
|
||||
}
|
||||
|
||||
static void BspSeatMoveCan_ErrorCallback(cy_en_canfd_bus_error_t error)
|
||||
{
|
||||
if(error == CY_CANFD_BUSOFF)
|
||||
{
|
||||
g_bspSeatMoveCanBusOff = 1u;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef BSP_SEAT_MOVE_CAN_H
|
||||
#define BSP_SEAT_MOVE_CAN_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t identifier;
|
||||
uint32_t data0;
|
||||
uint32_t data1;
|
||||
uint8_t dlc;
|
||||
} bsp_seat_move_can_frame_t;
|
||||
|
||||
bool BspSeatMoveCan_Init(void);
|
||||
bool BspSeatMoveCan_Read(bsp_seat_move_can_frame_t *frame);
|
||||
bool BspSeatMoveCan_Send(uint32_t identifier, uint32_t data0, uint32_t data1);
|
||||
|
||||
extern volatile uint32_t g_bspSeatMoveCanInitStatus;
|
||||
extern volatile uint32_t g_bspSeatMoveCanRxCount;
|
||||
extern volatile uint32_t g_bspSeatMoveCanRxQueueOverflowCount;
|
||||
extern volatile uint32_t g_bspSeatMoveCanTxCount;
|
||||
extern volatile uint32_t g_bspSeatMoveCanTxBusyCount;
|
||||
extern volatile uint32_t g_bspSeatMoveCanLastRxId;
|
||||
extern volatile uint32_t g_bspSeatMoveCanLastTxId;
|
||||
extern volatile uint32_t g_bspSeatMoveCanLastTxStatus;
|
||||
extern volatile uint32_t g_bspSeatMoveCanBusOff;
|
||||
|
||||
#endif /* BSP_SEAT_MOVE_CAN_H */
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
#ifndef SEAT_BACKREST_HEATER_CONFIG_H
|
||||
#define SEAT_BACKREST_HEATER_CONFIG_H
|
||||
|
||||
#include "cy_project.h"
|
||||
#include "cy_device_headers.h"
|
||||
|
||||
/*
|
||||
* Schematic-confirmed backrest-heater path:
|
||||
* P16.7 / KBJRD -> R126 (1 kOhm) -> BTS7010-1EPA IN -> backrest heater.
|
||||
* The rev_d SDK maps P16.7 to TCPWM1 line 65.
|
||||
*/
|
||||
#define SEAT_BACKREST_HEATER_PWM_PORT GPIO_PRT16
|
||||
#define SEAT_BACKREST_HEATER_PWM_PIN (7u)
|
||||
#define SEAT_BACKREST_HEATER_PWM_GPIO_HSIOM P16_7_GPIO
|
||||
#define SEAT_BACKREST_HEATER_PWM_HSIOM P16_7_TCPWM1_LINE65
|
||||
#define SEAT_BACKREST_HEATER_PWM_TCPWM TCPWM1_GRP0_CNT65
|
||||
#define SEAT_BACKREST_HEATER_PWM_PCLK PCLK_TCPWM1_CLOCKS65
|
||||
|
||||
#define SEAT_BACKREST_HEATER_PWM_DIVIDER_NUMBER (3u)
|
||||
#define SEAT_BACKREST_HEATER_COUNTER_CLOCK_HZ (2000000u)
|
||||
#define SEAT_BACKREST_HEATER_PWM_FREQUENCY_HZ (100u)
|
||||
#define SEAT_BACKREST_HEATER_PWM_PERIOD_TICKS \
|
||||
(SEAT_BACKREST_HEATER_COUNTER_CLOCK_HZ / \
|
||||
SEAT_BACKREST_HEATER_PWM_FREQUENCY_HZ)
|
||||
|
||||
/* Three open-loop power levels. Tune only after thermal validation. */
|
||||
#define SEAT_BACKREST_HEATER_LOW_DUTY_PERCENT (30u)
|
||||
#define SEAT_BACKREST_HEATER_MEDIUM_DUTY_PERCENT (60u)
|
||||
#define SEAT_BACKREST_HEATER_HIGH_DUTY_PERCENT (90u)
|
||||
#define SEAT_BACKREST_HEATER_DEFAULT_LEVEL (0u)
|
||||
|
||||
#define SEAT_BACKREST_HEATER_TASK_PERIOD_US (1000u)
|
||||
/*
|
||||
* Do not sample at the 10 ms PWM period. Equal periods phase-lock the ADC
|
||||
* to one PWM point and can report zero current continuously for a healthy
|
||||
* low-duty heater. Seven milliseconds walks through every PWM phase while
|
||||
* remaining slow enough for the existing SAR ADC service.
|
||||
*/
|
||||
#define SEAT_BACKREST_HEATER_SENSE_SAMPLE_MS (7u)
|
||||
#define SEAT_BACKREST_HEATER_SENSE_MAX_ERRORS (3u)
|
||||
#define SEAT_BACKREST_HEATER_MAX_ACTIVE_TIME_MS (600000u)
|
||||
|
||||
/*
|
||||
* Vehicle CAN4 wiring proven by D:\wcl\can and Seat_Fan_demo:
|
||||
* P3.7 RX, P3.6 TX, P3.1 high enables the board TJA1044 circuit.
|
||||
*/
|
||||
#define SEAT_BACKREST_HEATER_CAN_TYPE CY_CANFD1_2_TYPE
|
||||
#define SEAT_BACKREST_HEATER_CAN_RX_PORT GPIO_PRT3
|
||||
#define SEAT_BACKREST_HEATER_CAN_RX_PIN (7u)
|
||||
#define SEAT_BACKREST_HEATER_CAN_RX_MUX P3_7_CANFD1_TTCAN_RX2
|
||||
#define SEAT_BACKREST_HEATER_CAN_TX_PORT GPIO_PRT3
|
||||
#define SEAT_BACKREST_HEATER_CAN_TX_PIN (6u)
|
||||
#define SEAT_BACKREST_HEATER_CAN_TX_MUX P3_6_CANFD1_TTCAN_TX2
|
||||
#define SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_PORT GPIO_PRT3
|
||||
#define SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_PIN (1u)
|
||||
#define SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_GPIO_HSIOM P3_1_GPIO
|
||||
#define SEAT_BACKREST_HEATER_CAN_TRANSCEIVER_ENABLE (1u)
|
||||
#define SEAT_BACKREST_HEATER_CAN_PCLK PCLK_CANFD1_CLOCK_CAN2
|
||||
#define SEAT_BACKREST_HEATER_CAN_IRQN canfd_1_interrupts0_2_IRQn
|
||||
#define SEAT_BACKREST_HEATER_CAN_CPU_IRQ CPUIntIdx2_IRQn
|
||||
#define SEAT_BACKREST_HEATER_CAN_DIVIDER_NUMBER (0u)
|
||||
#define SEAT_BACKREST_HEATER_CAN_CLOCK_HZ (40000000u)
|
||||
#define SEAT_BACKREST_HEATER_CAN_TX_BUFFER_COUNT (4u)
|
||||
#define SEAT_BACKREST_HEATER_CAN_RX_FIFO0_ELEMENTS (8u)
|
||||
#define SEAT_BACKREST_HEATER_CAN_RX_QUEUE_DEPTH (8u)
|
||||
|
||||
/* Classic CAN matrix messages, 11-bit IDs, 8-byte payloads, Intel bit order. */
|
||||
#define SEAT_BACKREST_HEATER_CAN_CONTROL_29E_ID (0x29Eu)
|
||||
#define SEAT_BACKREST_HEATER_CAN_CONFIG_2AA_ID (0x2AAu)
|
||||
#define SEAT_BACKREST_HEATER_CAN_MODE_3CE_ID (0x3CEu)
|
||||
#define SEAT_BACKREST_HEATER_CAN_SWITCH_42A_ID (0x42Au)
|
||||
#define SEAT_BACKREST_HEATER_CAN_FEEDBACK_4FA_ID (0x4FAu)
|
||||
#define SEAT_BACKREST_HEATER_CAN_DLC (8u)
|
||||
#define SEAT_BACKREST_HEATER_CAN_FEEDBACK_PERIOD_MS (100u)
|
||||
#define SEAT_BACKREST_HEATER_CAN_ACCEPT_42A_COMMAND (1u)
|
||||
#define SEAT_BACKREST_HEATER_DEFAULT_CAN_GEAR (2u)
|
||||
|
||||
/* Safety watchdog and retained C-SPY session latch, derived from Seat_Fan_demo. */
|
||||
#define SEAT_BACKREST_HEATER_WDT_TIMEOUT_TICKS (3200u)
|
||||
#define SEAT_BACKREST_HEATER_DEBUG_BREG_INDEX (3u)
|
||||
#define SEAT_BACKREST_HEATER_DEBUG_ACTIVE_MAGIC (0x48444247u) /* "HDBG" */
|
||||
#define SEAT_BACKREST_HEATER_DEBUG_EXIT_MAGIC (0x484F4646u) /* "HOFF" */
|
||||
|
||||
/*
|
||||
* Schematic-confirmed diagnostic current-sense path:
|
||||
* KBJRD-AD -> P12.2 / ADC[1]_6. The BTS7010 IS pin uses a 1.2 kOhm
|
||||
* sense resistor and the schematic annotates K=5000. The calculated current
|
||||
* is for bench visibility only; production thresholds require calibration.
|
||||
*/
|
||||
#define SEAT_BACKREST_HEATER_SENSE_ENABLE (1u)
|
||||
#define SEAT_BACKREST_HEATER_SENSE_PORT GPIO_PRT12
|
||||
#define SEAT_BACKREST_HEATER_SENSE_PIN (2u)
|
||||
#define SEAT_BACKREST_HEATER_SENSE_GPIO_HSIOM P12_2_GPIO
|
||||
#define SEAT_BACKREST_HEATER_SENSE_RESISTOR_OHM (1200u)
|
||||
#define SEAT_BACKREST_HEATER_SENSE_KILIS (5000u)
|
||||
|
||||
/* BTS7010 control facts confirmed on the power-driver schematic page. */
|
||||
#define SEAT_BACKREST_HEATER_BTS7010_IN_ACTIVE_HIGH (1u)
|
||||
#define SEAT_BACKREST_HEATER_BTS7010_DEN_MCU_CONTROLLED (0u)
|
||||
|
||||
#if !defined(CYT4BFBCJE) || !defined(CY_MCU_rev_d)
|
||||
#error "Seat_Controller_demo requires CYT4BFBCJE rev_d headers."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_BACKREST_HEATER_COUNTER_CLOCK_HZ % \
|
||||
SEAT_BACKREST_HEATER_PWM_FREQUENCY_HZ) != 0u)
|
||||
#error "The heater counter clock must divide evenly by the PWM frequency."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_BACKREST_HEATER_PWM_PERIOD_TICKS == 0u) || \
|
||||
(SEAT_BACKREST_HEATER_PWM_PERIOD_TICKS > 65535u))
|
||||
#error "The heater PWM period does not fit TCPWM1 group 0 counter 65."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_BACKREST_HEATER_LOW_DUTY_PERCENT == 0u) || \
|
||||
(SEAT_BACKREST_HEATER_LOW_DUTY_PERCENT >= \
|
||||
SEAT_BACKREST_HEATER_MEDIUM_DUTY_PERCENT) || \
|
||||
(SEAT_BACKREST_HEATER_MEDIUM_DUTY_PERCENT >= \
|
||||
SEAT_BACKREST_HEATER_HIGH_DUTY_PERCENT) || \
|
||||
(SEAT_BACKREST_HEATER_HIGH_DUTY_PERCENT > 100u))
|
||||
#error "Heater duties must be ordered LOW < MEDIUM < HIGH <= 100."
|
||||
#endif
|
||||
|
||||
#if (SEAT_BACKREST_HEATER_DEFAULT_LEVEL > 3u)
|
||||
#error "Default heater level must be 0 (off) through 3 (high)."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_BACKREST_HEATER_CAN_CONTROL_29E_ID > 0x7FFu) || \
|
||||
(SEAT_BACKREST_HEATER_CAN_CONFIG_2AA_ID > 0x7FFu) || \
|
||||
(SEAT_BACKREST_HEATER_CAN_MODE_3CE_ID > 0x7FFu) || \
|
||||
(SEAT_BACKREST_HEATER_CAN_SWITCH_42A_ID > 0x7FFu) || \
|
||||
(SEAT_BACKREST_HEATER_CAN_FEEDBACK_4FA_ID > 0x7FFu))
|
||||
#error "Seat heating CAN IDs must be 11-bit standard identifiers."
|
||||
#endif
|
||||
|
||||
#if (SEAT_BACKREST_HEATER_CAN_RX_QUEUE_DEPTH < 5u)
|
||||
#error "The heater CAN receive queue must hold at least five frames."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_BACKREST_HEATER_DEFAULT_CAN_GEAR == 0u) || \
|
||||
(SEAT_BACKREST_HEATER_DEFAULT_CAN_GEAR > 3u))
|
||||
#error "Default heater CAN gear must be in the range 1 through 3."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_BACKREST_HEATER_SENSE_SAMPLE_MS == 0u) || \
|
||||
(SEAT_BACKREST_HEATER_SENSE_MAX_ERRORS == 0u) || \
|
||||
(SEAT_BACKREST_HEATER_MAX_ACTIVE_TIME_MS == 0u))
|
||||
#error "Heater sample period and maximum active time must be non-zero."
|
||||
#endif
|
||||
|
||||
#if (SEAT_BACKREST_HEATER_DEBUG_BREG_INDEX >= SRSS_BACKUP_NUM_BREG)
|
||||
#error "The selected heater backup register is not present on this device."
|
||||
#endif
|
||||
|
||||
#endif /* SEAT_BACKREST_HEATER_CONFIG_H */
|
||||
@@ -0,0 +1,71 @@
|
||||
#ifndef SEAT_CURRENT_ADC_CONFIG_H
|
||||
#define SEAT_CURRENT_ADC_CONFIG_H
|
||||
|
||||
#include "cy_project.h"
|
||||
#include "cy_device_headers.h"
|
||||
|
||||
/*
|
||||
* PASS0 SAR1 is shared by all seat-current measurements. The schematic
|
||||
* connects VREFH and the DRV8718 AREF rail to filtered 5 V, so raw-to-voltage
|
||||
* calculations must use 5000 mV rather than the GPIO-domain 3.3 V supply.
|
||||
*
|
||||
* Logical motor mapping:
|
||||
* M0 horizontal : ZYTTKZDY-AD, P10.6, ADC[1]_2
|
||||
* M1 seat pan : JXBKZDY-AD, P12.1, ADC[1]_5
|
||||
* M2 backrest : ZYKBKZDY-AD, P10.7, ADC[1]_3
|
||||
* M3 legrest : ZYGDKZDY-AD, P10.5, ADC[1]_1
|
||||
* heater current : KBJRD-AD, P12.2, ADC[1]_6
|
||||
* fan current : FSDY-AD, P12.6, ADC[1]_10
|
||||
*/
|
||||
#define SEAT_CURRENT_ADC_INSTANCE PASS0_SAR1
|
||||
#define SEAT_CURRENT_ADC_PCLK PCLK_PASS0_CLOCK_SAR1
|
||||
#define SEAT_CURRENT_ADC_DIVIDER_NUMBER (4u)
|
||||
#define SEAT_CURRENT_ADC_REFERENCE_MV (5000u)
|
||||
#define SEAT_CURRENT_ADC_FULL_SCALE (4095u)
|
||||
#define SEAT_CURRENT_ADC_OPERATION_FREQ_MAX_HZ (13340000u)
|
||||
#define SEAT_CURRENT_ADC_SAMPLE_TIME_MIN_NS (600ull)
|
||||
#define SEAT_CURRENT_ADC_POLL_TIMEOUT (100000u)
|
||||
|
||||
#define SEAT_CURRENT_M0_PORT GPIO_PRT10
|
||||
#define SEAT_CURRENT_M0_PIN (6u)
|
||||
#define SEAT_CURRENT_M0_GPIO_HSIOM P10_6_GPIO
|
||||
#define SEAT_CURRENT_M0_CHANNEL PASS0_SAR1_CH2
|
||||
#define SEAT_CURRENT_M0_PIN_ADDRESS CY_ADC_PIN_ADDRESS_AN2
|
||||
|
||||
#define SEAT_CURRENT_M1_PORT GPIO_PRT12
|
||||
#define SEAT_CURRENT_M1_PIN (1u)
|
||||
#define SEAT_CURRENT_M1_GPIO_HSIOM P12_1_GPIO
|
||||
#define SEAT_CURRENT_M1_CHANNEL PASS0_SAR1_CH5
|
||||
#define SEAT_CURRENT_M1_PIN_ADDRESS CY_ADC_PIN_ADDRESS_AN5
|
||||
|
||||
#define SEAT_CURRENT_M2_PORT GPIO_PRT10
|
||||
#define SEAT_CURRENT_M2_PIN (7u)
|
||||
#define SEAT_CURRENT_M2_GPIO_HSIOM P10_7_GPIO
|
||||
#define SEAT_CURRENT_M2_CHANNEL PASS0_SAR1_CH3
|
||||
#define SEAT_CURRENT_M2_PIN_ADDRESS CY_ADC_PIN_ADDRESS_AN3
|
||||
|
||||
#define SEAT_CURRENT_M3_PORT GPIO_PRT10
|
||||
#define SEAT_CURRENT_M3_PIN (5u)
|
||||
#define SEAT_CURRENT_M3_GPIO_HSIOM P10_5_GPIO
|
||||
#define SEAT_CURRENT_M3_CHANNEL PASS0_SAR1_CH1
|
||||
#define SEAT_CURRENT_M3_PIN_ADDRESS CY_ADC_PIN_ADDRESS_AN1
|
||||
|
||||
#define SEAT_CURRENT_HEATER_PORT GPIO_PRT12
|
||||
#define SEAT_CURRENT_HEATER_PIN (2u)
|
||||
#define SEAT_CURRENT_HEATER_GPIO_HSIOM P12_2_GPIO
|
||||
#define SEAT_CURRENT_HEATER_CHANNEL PASS0_SAR1_CH6
|
||||
#define SEAT_CURRENT_HEATER_PIN_ADDRESS CY_ADC_PIN_ADDRESS_AN6
|
||||
|
||||
#define SEAT_CURRENT_FAN_PORT GPIO_PRT12
|
||||
#define SEAT_CURRENT_FAN_PIN (6u)
|
||||
#define SEAT_CURRENT_FAN_GPIO_HSIOM P12_6_GPIO
|
||||
#define SEAT_CURRENT_FAN_CHANNEL PASS0_SAR1_CH10
|
||||
#define SEAT_CURRENT_FAN_PIN_ADDRESS CY_ADC_PIN_ADDRESS_AN10
|
||||
|
||||
#define SEAT_CURRENT_ADC_PORT_ADDRESS CY_ADC_PORT_ADDRESS_SARMUX0
|
||||
|
||||
#if !defined(CYT4BFBCJE) || !defined(CY_MCU_rev_d)
|
||||
#error "Seat current ADC mapping requires CYT4BFBCJE rev_d headers."
|
||||
#endif
|
||||
|
||||
#endif /* SEAT_CURRENT_ADC_CONFIG_H */
|
||||
@@ -0,0 +1,139 @@
|
||||
#ifndef SEAT_FAN_CONFIG_H
|
||||
#define SEAT_FAN_CONFIG_H
|
||||
|
||||
#include "cy_project.h"
|
||||
#include "cy_device_headers.h"
|
||||
|
||||
/*
|
||||
* Backrest fan:
|
||||
* P11.1 -> KBFSDY-PWM-IN -> BTS7030 IN0 -> backrest fan.
|
||||
* The schematic name "PWM0-60" maps to TCPWM1 group 0 counter 60 in SDL.
|
||||
*/
|
||||
#define SEAT_FAN_PWM_PORT GPIO_PRT11
|
||||
#define SEAT_FAN_PWM_PIN (1u)
|
||||
#define SEAT_FAN_PWM_GPIO_HSIOM P11_1_GPIO
|
||||
#define SEAT_FAN_PWM_HSIOM P11_1_TCPWM1_LINE60
|
||||
#define SEAT_FAN_PWM_TCPWM TCPWM1_GRP0_CNT60
|
||||
#define SEAT_FAN_PWM_PCLK PCLK_TCPWM1_CLOCKS60
|
||||
|
||||
/*
|
||||
* Seat-cushion fan output is unused in this first version and must stay low:
|
||||
* P11.2 -> ZDFSDY-PWM-IN.
|
||||
*/
|
||||
#define SEAT_FAN_UNUSED_PORT GPIO_PRT11
|
||||
#define SEAT_FAN_UNUSED_PIN (2u)
|
||||
#define SEAT_FAN_UNUSED_GPIO_HSIOM P11_2_GPIO
|
||||
|
||||
#define SEAT_FAN_PWM_DIVIDER_NUMBER (0u)
|
||||
#define SEAT_FAN_COUNTER_CLOCK_HZ (2000000u)
|
||||
#define SEAT_FAN_PWM_FREQUENCY_HZ (100u)
|
||||
#define SEAT_FAN_PWM_PERIOD_TICKS \
|
||||
(SEAT_FAN_COUNTER_CLOCK_HZ / SEAT_FAN_PWM_FREQUENCY_HZ)
|
||||
|
||||
#define SEAT_FAN_STARTUP_DUTY_PERCENT (100u)
|
||||
#define SEAT_FAN_RUNNING_DUTY_PERCENT (70u)
|
||||
#define SEAT_FAN_STARTUP_TIME_US (2000000u)
|
||||
#define SEAT_FAN_DEBUG_POLL_TIME_US (1000u)
|
||||
#define SEAT_FAN_WDT_TIMEOUT_TICKS (3200u)
|
||||
|
||||
/* CAN-controlled application timing and the three physical fan levels. */
|
||||
#define SEAT_FAN_TASK_PERIOD_US (1000u)
|
||||
#define SEAT_FAN_STARTUP_TIME_MS (SEAT_FAN_STARTUP_TIME_US / 1000u)
|
||||
#define SEAT_FAN_GEAR1_DUTY_PERCENT (50u)
|
||||
#define SEAT_FAN_GEAR2_DUTY_PERCENT (70u)
|
||||
#define SEAT_FAN_GEAR3_DUTY_PERCENT (100u)
|
||||
#define SEAT_FAN_DEFAULT_GEAR (2u)
|
||||
|
||||
/*
|
||||
* Vehicle CAN4 wiring proven by D:\wcl\can:
|
||||
* P3.7 RX, P3.6 TX, P3.1 high enables the board TJA1044 circuit.
|
||||
*/
|
||||
#define SEAT_FAN_CAN_TYPE CY_CANFD1_2_TYPE
|
||||
#define SEAT_FAN_CAN_RX_PORT GPIO_PRT3
|
||||
#define SEAT_FAN_CAN_RX_PIN (7u)
|
||||
#define SEAT_FAN_CAN_RX_MUX P3_7_CANFD1_TTCAN_RX2
|
||||
#define SEAT_FAN_CAN_TX_PORT GPIO_PRT3
|
||||
#define SEAT_FAN_CAN_TX_PIN (6u)
|
||||
#define SEAT_FAN_CAN_TX_MUX P3_6_CANFD1_TTCAN_TX2
|
||||
#define SEAT_FAN_CAN_TRANSCEIVER_PORT GPIO_PRT3
|
||||
#define SEAT_FAN_CAN_TRANSCEIVER_PIN (1u)
|
||||
#define SEAT_FAN_CAN_TRANSCEIVER_GPIO_HSIOM P3_1_GPIO
|
||||
#define SEAT_FAN_CAN_TRANSCEIVER_ENABLE (1u)
|
||||
#define SEAT_FAN_CAN_PCLK PCLK_CANFD1_CLOCK_CAN2
|
||||
#define SEAT_FAN_CAN_IRQN canfd_1_interrupts0_2_IRQn
|
||||
#define SEAT_FAN_CAN_CPU_IRQ CPUIntIdx2_IRQn
|
||||
#define SEAT_FAN_CAN_DIVIDER_NUMBER (0u)
|
||||
#define SEAT_FAN_CAN_CLOCK_HZ (40000000u)
|
||||
#define SEAT_FAN_CAN_TX_BUFFER_COUNT (4u)
|
||||
#define SEAT_FAN_CAN_RX_FIFO0_ELEMENTS (8u)
|
||||
#define SEAT_FAN_CAN_RX_QUEUE_DEPTH (8u)
|
||||
|
||||
/* Classic CAN matrix messages, 11-bit IDs, 8-byte payloads, Intel bit order. */
|
||||
#define SEAT_FAN_CAN_CONTROL_29E_ID (0x29Eu)
|
||||
#define SEAT_FAN_CAN_CONFIG_2AA_ID (0x2AAu)
|
||||
#define SEAT_FAN_CAN_SWITCH_42A_ID (0x42Au)
|
||||
#define SEAT_FAN_CAN_FEEDBACK_4FA_ID (0x4FAu)
|
||||
#define SEAT_FAN_CAN_DLC (8u)
|
||||
#define SEAT_FAN_CAN_FEEDBACK_PERIOD_MS (100u)
|
||||
#define SEAT_FAN_CAN_ACCEPT_42A_COMMAND (1u)
|
||||
|
||||
/* FSDY-AD is P12.6 / ADC[1]_10 on the shared seat-current ADC. */
|
||||
#define SEAT_FAN_CURRENT_SAMPLE_MS (10u)
|
||||
|
||||
/*
|
||||
* BREG3 retains the debug-session state through debug/XRES/WDT resets.
|
||||
* DEBUG_ACTIVE is written by firmware as soon as it observes C_DEBUGEN, so a
|
||||
* debugger-induced reset cannot accidentally restart the fan even if the
|
||||
* C-SPY exit hook was skipped. DEBUG_EXIT is written when detach is observed
|
||||
* or by the C-SPY exit hook. A genuine POR releases either marker.
|
||||
*/
|
||||
#define SEAT_FAN_DEBUG_SESSION_BREG_INDEX (3u)
|
||||
#define SEAT_FAN_DEBUG_ACTIVE_MAGIC (0x44424741u) /* ASCII "DBGA" */
|
||||
#define SEAT_FAN_DEBUG_EXIT_MAGIC (0x5346414Eu) /* ASCII "SFAN" */
|
||||
|
||||
#if !defined(CYT4BFBCJE) || !defined(CY_MCU_rev_d)
|
||||
#error "Seat_Controller_demo must be built for CYT4BFBCJE with the rev_d headers."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_FAN_COUNTER_CLOCK_HZ % SEAT_FAN_PWM_FREQUENCY_HZ) != 0u)
|
||||
#error "The TCPWM counter clock must divide evenly by the requested PWM frequency."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_FAN_PWM_PERIOD_TICKS == 0u) || (SEAT_FAN_PWM_PERIOD_TICKS > 65535u))
|
||||
#error "The PWM period does not fit TCPWM1 group 0 counter 60."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_FAN_STARTUP_TIME_US % SEAT_FAN_DEBUG_POLL_TIME_US) != 0u)
|
||||
#error "The startup duration must be an integer number of debug polling periods."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_FAN_STARTUP_TIME_US % 1000u) != 0u)
|
||||
#error "The fan startup time must be an integer number of milliseconds."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_FAN_GEAR1_DUTY_PERCENT > SEAT_FAN_GEAR2_DUTY_PERCENT) || \
|
||||
(SEAT_FAN_GEAR2_DUTY_PERCENT > SEAT_FAN_GEAR3_DUTY_PERCENT) || \
|
||||
(SEAT_FAN_GEAR3_DUTY_PERCENT > 100u))
|
||||
#error "Fan gear duty percentages must be monotonic and no greater than 100."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_FAN_DEFAULT_GEAR == 0u) || (SEAT_FAN_DEFAULT_GEAR > 3u))
|
||||
#error "The default physical fan gear must be in the range 1 through 3."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_FAN_CAN_CONTROL_29E_ID > 0x7FFu) || \
|
||||
(SEAT_FAN_CAN_CONFIG_2AA_ID > 0x7FFu) || \
|
||||
(SEAT_FAN_CAN_SWITCH_42A_ID > 0x7FFu) || \
|
||||
(SEAT_FAN_CAN_FEEDBACK_4FA_ID > 0x7FFu))
|
||||
#error "Seat ventilation CAN IDs must be 11-bit standard identifiers."
|
||||
#endif
|
||||
|
||||
#if (SEAT_FAN_CAN_RX_QUEUE_DEPTH < 4u)
|
||||
#error "The CAN receive queue must hold at least four frames."
|
||||
#endif
|
||||
|
||||
#if (SEAT_FAN_DEBUG_SESSION_BREG_INDEX >= SRSS_BACKUP_NUM_BREG)
|
||||
#error "The selected backup register is not present on this device."
|
||||
#endif
|
||||
|
||||
#endif /* SEAT_FAN_CONFIG_H */
|
||||
@@ -0,0 +1,150 @@
|
||||
#ifndef SEAT_MOVE_CONFIG_H
|
||||
#define SEAT_MOVE_CONFIG_H
|
||||
|
||||
#include "cy_project.h"
|
||||
#include "cy_device_headers.h"
|
||||
|
||||
/* This configuration is intentionally tied to the timed-only IAR target. */
|
||||
#if !defined(PASSENGER_SEAT_TIMED_ONLY)
|
||||
#error "Build this source only from Passenger_Seat_Timed_Controller_demo."
|
||||
#endif
|
||||
|
||||
#define SEAT_MOVE_MOTOR_COUNT (4u)
|
||||
#define SEAT_MOVE_ACTIVE_MOTOR_MASK (0x0Fu)
|
||||
#define SEAT_MOVE_TASK_PERIOD_US (1000u)
|
||||
#define SEAT_MOVE_START_STAGGER_MS (100u)
|
||||
#define SEAT_MOVE_MAX_CONCURRENT_MOTORS (4u)
|
||||
|
||||
/* Timed-only CAN limits. ParamA is duration in ms. */
|
||||
#define SEAT_TIMED_MIN_DURATION_MS (300u)
|
||||
#define SEAT_TIMED_M0_MAX_DURATION_MS (30000u) /* horizontal */
|
||||
#define SEAT_TIMED_M1_MAX_DURATION_MS (20000u) /* seat-pan */
|
||||
#define SEAT_TIMED_M2_MAX_DURATION_MS (30000u) /* backrest */
|
||||
#define SEAT_TIMED_M3_MAX_DURATION_MS (25000u) /* legrest */
|
||||
#define SEAT_TIMED_LEVEL_MIN_X10 (300u)
|
||||
#define SEAT_TIMED_LEVEL_MAX_X10 (1000u)
|
||||
|
||||
/* Logical MotorID and connected DRV8718 channel are identical. */
|
||||
#define SEAT_MOVE_LOGICAL_M0_PHYSICAL_MODE (0u)
|
||||
#define SEAT_MOVE_LOGICAL_M1_PHYSICAL_MODE (1u)
|
||||
#define SEAT_MOVE_LOGICAL_M2_PHYSICAL_MODE (2u)
|
||||
#define SEAT_MOVE_LOGICAL_M3_PHYSICAL_MODE (3u)
|
||||
|
||||
/* Retained by the verified motor manager; timed requests provide duty. */
|
||||
#define SEAT_MOVE_M0_DEFAULT_TIMEOUT_MS (12000u)
|
||||
#define SEAT_MOVE_M1_DEFAULT_TIMEOUT_MS (8000u)
|
||||
#define SEAT_MOVE_M2_DEFAULT_TIMEOUT_MS (12000u)
|
||||
#define SEAT_MOVE_M3_DEFAULT_TIMEOUT_MS (30000u)
|
||||
#define SEAT_MOVE_M0_DEFAULT_DUTY_PERCENT (90u)
|
||||
#define SEAT_MOVE_M1_DEFAULT_DUTY_PERCENT (90u)
|
||||
#define SEAT_MOVE_M2_DEFAULT_DUTY_PERCENT (90u)
|
||||
#define SEAT_MOVE_M3_DEFAULT_DUTY_PERCENT (50u)
|
||||
#define SEAT_MOVE_M3_BREAKAWAY_DUTY_PERCENT (50u)
|
||||
#define SEAT_MOVE_POSITION_TARGET_HALL_TOLERANCE (4u)
|
||||
|
||||
/* CAN4, classic CAN, 500 kbit/s. */
|
||||
#define SEAT_MOVE_CAN_TYPE CY_CANFD1_2_TYPE
|
||||
#define SEAT_MOVE_CAN_RX_PORT GPIO_PRT3
|
||||
#define SEAT_MOVE_CAN_RX_PIN (7u)
|
||||
#define SEAT_MOVE_CAN_RX_MUX P3_7_CANFD1_TTCAN_RX2
|
||||
#define SEAT_MOVE_CAN_TX_PORT GPIO_PRT3
|
||||
#define SEAT_MOVE_CAN_TX_PIN (6u)
|
||||
#define SEAT_MOVE_CAN_TX_MUX P3_6_CANFD1_TTCAN_TX2
|
||||
#define SEAT_MOVE_CAN_TRANSCEIVER_PORT GPIO_PRT3
|
||||
#define SEAT_MOVE_CAN_TRANSCEIVER_PIN (1u)
|
||||
#define SEAT_MOVE_CAN_TRANSCEIVER_GPIO_HSIOM P3_1_GPIO
|
||||
#define SEAT_MOVE_CAN_TRANSCEIVER_ENABLE (1u)
|
||||
#define SEAT_MOVE_CAN_PCLK PCLK_CANFD1_CLOCK_CAN2
|
||||
#define SEAT_MOVE_CAN_IRQN canfd_1_interrupts0_2_IRQn
|
||||
#define SEAT_MOVE_CAN_CPU_IRQ CPUIntIdx2_IRQn
|
||||
#define SEAT_MOVE_CAN_DIVIDER_NUMBER (0u)
|
||||
#define SEAT_MOVE_CAN_CLOCK_HZ (40000000u)
|
||||
#define SEAT_MOVE_CAN_TX_BUFFER_COUNT (8u)
|
||||
#define SEAT_MOVE_CAN_RX_FIFO0_ELEMENTS (8u)
|
||||
#define SEAT_MOVE_CAN_RX_QUEUE_DEPTH (16u)
|
||||
#define SEAT_MOVE_CAN_DLC (8u)
|
||||
#define SEAT_MOVE_CAN_PROTOCOL_VERSION (1u)
|
||||
|
||||
#define SEAT_MOVE_CAN_COMMAND_ID (0x300u)
|
||||
#define SEAT_MOVE_CAN_SYSTEM_STATUS_ID (0x301u)
|
||||
#define SEAT_MOVE_CAN_MOTOR_STATUS_ID (0x302u)
|
||||
#define SEAT_MOVE_CAN_DIAGNOSTIC_ID (0x303u)
|
||||
#define SEAT_MOVE_CAN_CURRENT_DIAGNOSTIC_ID (0x304u)
|
||||
#define SEAT_MOVE_CAN_FIRMWARE_ID_ID (0x307u)
|
||||
#define SEAT_MOVE_FIRMWARE_REVISION (15u)
|
||||
#define SEAT_MOVE_FIRMWARE_BUILD_ID (17u)
|
||||
|
||||
#define SEAT_MOVE_SYSTEM_STATUS_PERIOD_MS (100u)
|
||||
#define SEAT_MOVE_MOTOR_STATUS_POLL_MS (25u)
|
||||
#define SEAT_MOVE_DIAGNOSTIC_POLL_MS (25u)
|
||||
#define SEAT_MOVE_FIRMWARE_ID_PERIOD_MS (500u)
|
||||
|
||||
/* Current-aware stall detection remains active for timed movement. */
|
||||
#define SEAT_MOVE_MOTOR_CURRENT_SAMPLE_MS (10u)
|
||||
#define SEAT_MOVE_MOTOR_CURRENT_MAX_AGE_MS (100u)
|
||||
#define SEAT_MOVE_MOTOR_CURRENT_BASELINE_FILTER_SHIFT (3u)
|
||||
#define SEAT_MOVE_MOTOR_STALL_CURRENT_CONFIRM_MS (200u)
|
||||
#define SEAT_MOVE_MOTOR_NO_MOTION_TIMEOUT_MS (5000u)
|
||||
#define SEAT_MOVE_M0_STALL_CURRENT_DELTA_RAW (500u)
|
||||
#define SEAT_MOVE_M1_STALL_CURRENT_DELTA_RAW (500u)
|
||||
#define SEAT_MOVE_M2_STALL_CURRENT_DELTA_RAW (500u)
|
||||
#define SEAT_MOVE_M3_STALL_CURRENT_DELTA_RAW (500u)
|
||||
#define SEAT_MOVE_MOTOR_CURRENT_MAX_ERRORS (3u)
|
||||
|
||||
/* Debug-detach and watchdog safety. HIL registers remain internal to the
|
||||
* reused safety manager; this image exposes no HIL CAN command/filter. */
|
||||
#define SEAT_MOVE_DEBUG_SESSION_BREG_INDEX (3u)
|
||||
#define SEAT_MOVE_DEBUG_ACTIVE_MAGIC (0x4D4F5641u)
|
||||
#define SEAT_MOVE_DEBUG_EXIT_MAGIC (0x4D4F5645u)
|
||||
#define SEAT_MOVE_WDT_TIMEOUT_TICKS (3200u)
|
||||
#define SEAT_MOVE_HIL_WDT_MAGIC_BREG_INDEX (0u)
|
||||
#define SEAT_MOVE_HIL_WDT_TOKEN_BREG_INDEX (1u)
|
||||
#define SEAT_MOVE_HIL_WDT_CHECK_BREG_INDEX (2u)
|
||||
#define SEAT_MOVE_HIL_WDT_MARKER (0x48494C36u)
|
||||
|
||||
#if !defined(CYT4BFBCJE) || !defined(CY_MCU_rev_d)
|
||||
#error "Timed passenger-seat firmware requires CYT4BFBCJE rev_d."
|
||||
#endif
|
||||
|
||||
#if (SEAT_MOVE_ACTIVE_MOTOR_MASK != 0x0Fu)
|
||||
#error "All four passenger-seat motor outputs must be enabled."
|
||||
#endif
|
||||
|
||||
#if (SEAT_MOVE_MAX_CONCURRENT_MOTORS == 0u) || \
|
||||
(SEAT_MOVE_MAX_CONCURRENT_MOTORS > SEAT_MOVE_MOTOR_COUNT)
|
||||
#error "Concurrent motor budget must be between one and four."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_TIMED_MIN_DURATION_MS == 0u) || \
|
||||
(SEAT_TIMED_M0_MAX_DURATION_MS > 65535u) || \
|
||||
(SEAT_TIMED_M1_MAX_DURATION_MS > 65535u) || \
|
||||
(SEAT_TIMED_M2_MAX_DURATION_MS > 65535u) || \
|
||||
(SEAT_TIMED_M3_MAX_DURATION_MS > 65535u))
|
||||
#error "Timed-command duration limits must fit ParamA."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_MOVE_CAN_COMMAND_ID > 0x7FFu) || \
|
||||
(SEAT_MOVE_CAN_SYSTEM_STATUS_ID > 0x7FFu) || \
|
||||
(SEAT_MOVE_CAN_MOTOR_STATUS_ID > 0x7FFu) || \
|
||||
(SEAT_MOVE_CAN_DIAGNOSTIC_ID > 0x7FFu) || \
|
||||
(SEAT_MOVE_CAN_CURRENT_DIAGNOSTIC_ID > 0x7FFu) || \
|
||||
(SEAT_MOVE_CAN_FIRMWARE_ID_ID > 0x7FFu))
|
||||
#error "Seat movement CAN identifiers must be 11-bit standard IDs."
|
||||
#endif
|
||||
|
||||
#if (SEAT_MOVE_FIRMWARE_REVISION > 0x0Fu) || \
|
||||
(SEAT_MOVE_FIRMWARE_BUILD_ID > 0xFFu)
|
||||
#error "Firmware identity fields exceed their CAN encoding."
|
||||
#endif
|
||||
|
||||
#if ((SEAT_MOVE_MOTOR_CURRENT_SAMPLE_MS == 0u) || \
|
||||
(SEAT_MOVE_MOTOR_CURRENT_MAX_AGE_MS < \
|
||||
SEAT_MOVE_MOTOR_CURRENT_SAMPLE_MS) || \
|
||||
(SEAT_MOVE_MOTOR_STALL_CURRENT_CONFIRM_MS == 0u) || \
|
||||
(SEAT_MOVE_MOTOR_NO_MOTION_TIMEOUT_MS <= \
|
||||
SEAT_MOVE_MOTOR_STALL_CURRENT_CONFIRM_MS) || \
|
||||
(SEAT_MOVE_MOTOR_CURRENT_MAX_ERRORS == 0u))
|
||||
#error "Motor current/stall timing configuration is invalid."
|
||||
#endif
|
||||
|
||||
#endif /* SEAT_MOVE_CONFIG_H */
|
||||
@@ -0,0 +1,25 @@
|
||||
# Build information — 2026-09-16
|
||||
|
||||
- Project: `Passenger_Seat_Timed_Controller_demo.ewp`
|
||||
- Configuration: `rev_d`
|
||||
- IAR command-line builder: 9.2.2.10770
|
||||
- IAR ARM compiler/linker: 9.40.1.364
|
||||
- Result: 0 errors, 0 warnings
|
||||
- Read-only code: 40,626 bytes
|
||||
- Read-only data: 1,977 bytes
|
||||
- Read-write data: 6,182 bytes
|
||||
|
||||
Artifacts:
|
||||
|
||||
| File | SHA-256 |
|
||||
|---|---|
|
||||
| `IAR/rev_d/Exe/Passenger_Seat_Timed_Controller_demo.hex` | `7B47002B7B1A882A90717CE2727D60349B6C58CF0C1E95E48094C85EDB376CDC` |
|
||||
| `IAR/rev_d/Exe/Passenger_Seat_Timed_Controller_demo.out` | `B0C740CB2BE02008BC03803B0A3422D817ABD1CF2BF977156294FB04BBDFAB7F` |
|
||||
|
||||
The linker map contains `SeatMotor_MoveTimedDuty` as the sole linked
|
||||
`SeatMotor_Move*`/calibration/homing entry point. No dynamic-mode, position
|
||||
store, or thermal-controller application symbol is linked. The HEX contains
|
||||
the `PST1`, revision 15, build 17 identity payload.
|
||||
|
||||
This result is a compile/link verification only. No target was flashed and no
|
||||
physical actuator movement was performed during this build.
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
# 副驾座椅四轴定时控制固件
|
||||
|
||||
本目录是从 `Seat_Controller_demo` 独立出的副驾定时控制版本。原工程保持不变;本工程的 CAN 应用层只允许四轴定时运动,不提供位置、相对位移、回零、标定、动态模式或热控能力。
|
||||
|
||||
## IAR 工程
|
||||
|
||||
- 工程文件:`IAR/Passenger_Seat_Timed_Controller_demo.ewp`
|
||||
- 目标器件:Infineon TRAVEO T2G `CYT4BFBCJE`,`rev_d`
|
||||
- IAR 工程宏:`PASSENGER_SEAT_TIMED_ONLY=1`
|
||||
- HEX 输出:`Passenger_Seat_Timed_Controller_demo.hex`
|
||||
- 固件身份帧:CAN `0x307`,字节 0..3 为 ASCII `PST1`,Build ID 为 `17`
|
||||
|
||||
工程复用原固件已验证的 DRV8718、Hall、电流检测、堵转/端点保护、看门狗和调试器退出安全逻辑。加热和风扇应用没有链接进固件;其 BSP 只用于启动及异常路径中强制输出关闭。
|
||||
|
||||
## 四轴能力
|
||||
|
||||
| MotorID | 机构 | 最短时间 | 最长时间 | 实际占空比限制 |
|
||||
|---:|---|---:|---:|---:|
|
||||
| 0 | 水平前后 | 300 ms | 30000 ms | 50%..95% |
|
||||
| 1 | 坐垫升降 | 300 ms | 20000 ms | 50%..95% |
|
||||
| 2 | 靠背角度 | 300 ms | 30000 ms | 50%..95% |
|
||||
| 3 | 腿托升降 | 300 ms | 25000 ms | 固定上限 50% |
|
||||
|
||||
四轴可并发,启动间隔至少 100 ms。同一轴收到更新的定时命令时,先停止该轴,再执行新命令;不影响其他轴。定时运动不依赖绝对位置有效性,但端点、堵转、电流和驱动故障保护始终生效。
|
||||
|
||||
## CAN 命令
|
||||
|
||||
CAN4 使用经典 CAN、标准 11 位 ID、500 kbit/s。接收过滤器只接受 `0x300`,DLC 必须为 8。
|
||||
|
||||
`0x300` 的 8 字节按小端编码:
|
||||
|
||||
| 字节 | 字段 |
|
||||
|---|---|
|
||||
| B0 | Opcode |
|
||||
| B1 | Control:bit1:0 MotorID,bit3:2 Direction,bit5:4 ProtocolVersion=1,bit7:6=0 |
|
||||
| B3:B2 | Sequence,uint16 |
|
||||
| B5:B4 | ParamA,uint16 |
|
||||
| B7:B6 | ParamB,uint16 |
|
||||
|
||||
支持的 Opcode:
|
||||
|
||||
| Opcode | 功能 | Direction | ParamA | ParamB |
|
||||
|---:|---|---|---|---|
|
||||
| `0x03` | 定时运动 | `1` 向远端,`2` 向近端 | 时间,ms | 请求占空比 ×10,范围 300..1000 |
|
||||
| `0x08` | 停止单轴 | `0` | `0` | `0` |
|
||||
| `0x09` | 停止全部 | `0`,MotorID=`0` | `0` | `0` |
|
||||
| `0x0C` | 查询单轴状态 | `0` | `0` | `0` |
|
||||
| `0x0D` | 清除单轴任务故障 | `0` | `0xC33C` | `0` |
|
||||
|
||||
请求占空比会被安全范围约束:M0..M2 最终为 50%..95%,M3 不超过 50%。`STOP_ALL` 不受序列号新旧限制,可用于随时重新同步和急停;其他命令要求 16 位 Sequence 按环形序列递增,完全相同的重复帧返回 Duplicate。
|
||||
|
||||
以下运动 Opcode 固定返回 `BAD_OPCODE(3)`:
|
||||
|
||||
- `0x01` 绝对位置
|
||||
- `0x02` 相对位置
|
||||
- `0x0A` 行程标定
|
||||
- `0x0B` 已知行程回零
|
||||
- `0x0E` 启动动态模式
|
||||
- `0x0F` 停止动态模式
|
||||
|
||||
热控和 HIL 自愈帧不在硬件接收过滤器中,`0x306` 动态模式状态也不再发送。
|
||||
|
||||
## 状态反馈
|
||||
|
||||
保留与原座椅协议兼容的诊断帧:
|
||||
|
||||
- `0x301`:系统状态、ACK、拒绝原因、活动/故障轴掩码
|
||||
- `0x302`:单轴任务状态;定时运行状态值为 `3`
|
||||
- `0x303`:Hall、速度和故障诊断
|
||||
- `0x304`:电流诊断
|
||||
- `0x307`:固件身份 `PST1`
|
||||
|
||||
`0x301` 中动态模式位和标定位始终为 0。位置有效位及百分比只作为 Hall 诊断信息返回,不用于目标位置控制。
|
||||
|
||||
## 构建与校验
|
||||
|
||||
1. 用 IAR Embedded Workbench for Arm 打开 `IAR/Passenger_Seat_Timed_Controller_demo.ewp`。
|
||||
2. 选择 `rev_d` 配置并 Build。
|
||||
3. 烧录前通过 `0x307` 确认目标固件身份为 `PST1`。
|
||||
4. 烧录和台架运动测试期间保证座椅机构无人员/障碍物,先验证 `STOP_ALL`,再逐轴低时长测试。
|
||||
|
||||
仓库静态校验:
|
||||
|
||||
```text
|
||||
python firmware/t2g/Passenger_Seat_Timed_Controller_demo/Tests/audit_timed_only.py
|
||||
```
|
||||
|
||||
该脚本检查 IAR XML、工程引用、定时版编译宏、CAN 接收过滤器、允许的 Opcode,以及位置/动态/热控模块未被链接。
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,277 @@
|
||||
#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)
|
||||
|
||||
/*
|
||||
* 2026-07-30 endpoint-to-endpoint range calibration. Bench verification
|
||||
* established identity mapping: logical M0..M3 use physical mode 0..3.
|
||||
*/
|
||||
#define MOTOR_MODE0_DEFAULT_MAX_HALL_COUNT (480ul) /* horizontal */
|
||||
#define MOTOR_MODE0_MAX_POSITION_MM_X100 (21500ul)
|
||||
#define MOTOR_MODE1_DEFAULT_MAX_HALL_COUNT (374ul) /* seat pan */
|
||||
#define MOTOR_MODE1_MAX_VERTICAL_MM_X100 (5600ul)
|
||||
#define MOTOR_MODE1_MAX_HORIZONTAL_MM_X100 (5100ul)
|
||||
/* Compatibility name used by the generic scalar position API. */
|
||||
#define MOTOR_MODE1_MAX_ANGLE_DEG_X100 \
|
||||
MOTOR_MODE1_MAX_VERTICAL_MM_X100
|
||||
#define MOTOR_MODE2_DEFAULT_MAX_HALL_COUNT (917ul) /* backrest */
|
||||
#define MOTOR_MODE2_MAX_ANGLE_DEG_X100 (6800ul)
|
||||
#define MOTOR_MODE3_DEFAULT_MAX_HALL_COUNT (647ul) /* legrest */
|
||||
#define MOTOR_MODE3_MAX_ANGLE_DEG_X100 (7200ul)
|
||||
/* Compatibility name used by the generic scalar position API. */
|
||||
#define MOTOR_MODE3_MAX_POSITION_MM_X100 \
|
||||
MOTOR_MODE3_MAX_ANGLE_DEG_X100
|
||||
|
||||
#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 horizontalMmX100;
|
||||
uint32_t verticalMmX100;
|
||||
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
|
||||
{
|
||||
motor_mode_t mode;
|
||||
bool sampleValid;
|
||||
bool baselineValid;
|
||||
bool highCurrent;
|
||||
bool hallActivityLow;
|
||||
bool calibrating;
|
||||
uint16_t raw;
|
||||
uint16_t baselineRaw;
|
||||
uint16_t deltaRaw;
|
||||
uint16_t stallThresholdRaw;
|
||||
uint32_t sampleAgeMs;
|
||||
} motor_current_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: 215.00 mm is 21500 and
|
||||
* 68.00 degrees is 6800. positionValid is restored from a verified clean
|
||||
* record or becomes true after a known endpoint has been found.
|
||||
*
|
||||
* 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);
|
||||
uint8_t Motor_GetCurrentInfo(motor_mode_t mode, motor_current_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);
|
||||
/* Complete a commanded stop plus bounded Hall-coast tracking before a
|
||||
* safety decision that requires the mechanism to be physically settled. */
|
||||
bool Motor_WaitUntilStopped(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_ValidatePersistentState(motor_mode_t mode,
|
||||
const motor_persistent_state_t *state);
|
||||
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);
|
||||
/* Bench HIL support: invalidate only the stopped axis' absolute-position
|
||||
* confidence while preserving its measured Hall count and confirmed range.
|
||||
* Production command handling never calls this API. */
|
||||
uint8_t Motor_InvalidatePosition(motor_mode_t mode);
|
||||
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.
|
||||
* legTimeoutMs is the independent motion timeout applied to each endpoint leg.
|
||||
*/
|
||||
uint8_t Motor_Calibrate(motor_mode_t mode,
|
||||
motor_calibration_action_t action,
|
||||
uint32_t legTimeoutMs,
|
||||
motor_calibration_result_t *result);
|
||||
|
||||
/* Application override used to keep CAN/status/safety services alive while
|
||||
* the selected motor executes the blocking endpoint-calibration primitive. */
|
||||
void Motor_CalibrationServiceHook(void);
|
||||
|
||||
/* 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_GetPosition(motor_position_info_t *info);
|
||||
uint8_t Motor2_GetAngle(motor_position_info_t *info);
|
||||
uint8_t Motor3_GetAngle(motor_position_info_t *info);
|
||||
uint8_t Motor0_MoveToPositionMmX100(uint32_t positionMmX100);
|
||||
uint8_t Motor1_MoveToVerticalMmX100(uint32_t verticalMmX100);
|
||||
uint8_t Motor2_MoveToAngleDegX100(uint32_t angleDegX100);
|
||||
uint8_t Motor3_MoveToAngleDegX100(uint32_t angleDegX100);
|
||||
uint8_t Motor0_SetSpeedPlan(uint32_t durationMs, uint32_t distanceMmX100);
|
||||
uint8_t Motor1_SetSpeedPlan(uint32_t durationMs, uint32_t verticalMmX100);
|
||||
uint8_t Motor2_SetSpeedPlan(uint32_t durationMs, uint32_t angleDegX100);
|
||||
uint8_t Motor3_SetSpeedPlan(uint32_t durationMs, uint32_t angleDegX100);
|
||||
|
||||
#endif /* MOTOR_CONTROL_H */
|
||||
+1619
File diff suppressed because it is too large
Load Diff
+2359
File diff suppressed because it is too large
Load Diff
+185
@@ -0,0 +1,185 @@
|
||||
/* C-SPY host-side safety hook for the timed-only passenger-seat controller. */
|
||||
|
||||
execUserSetup()
|
||||
{
|
||||
/* A new Download and Debug session releases a previous debug-exit latch. */
|
||||
__writeMemory32(0x00000000, 0x4027100C, "Memory");
|
||||
__message "Passenger_Seat_Timed_Controller_demo: C-SPY setup cleared the debug-session latch.\n";
|
||||
}
|
||||
|
||||
execUserExit()
|
||||
{
|
||||
__var value;
|
||||
__var safe;
|
||||
|
||||
/* Retain safe-off across debug/XRES/WDT resets. */
|
||||
__writeMemory32(0x4D4F5645, 0x4027100C, "Memory");
|
||||
|
||||
/* Assert DRVOFF=P8.1 before touching PWM or pin muxing. */
|
||||
__writeMemory32(0x00000002, 0x40310408, "Memory");
|
||||
|
||||
/* Disable TCPWM1 group-0 counters IN1/IN2/IN3/IN4 and Hall timebase. */
|
||||
value = __readMemory32(0x40580600, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580600, "Memory");
|
||||
value = __readMemory32(0x40580680, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580680, "Memory");
|
||||
value = __readMemory32(0x40580700, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580700, "Memory");
|
||||
value = __readMemory32(0x40580980, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580980, "Memory");
|
||||
value = __readMemory32(0x40580A00, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580A00, "Memory");
|
||||
|
||||
/* Disable fan TCPWM60 and heater TCPWM65 before changing their muxes. */
|
||||
value = __readMemory32(0x40581E00, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40581E00, "Memory");
|
||||
value = __readMemory32(0x40582080, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40582080, "Memory");
|
||||
|
||||
/* Force P11.1/P11.2 fan paths and P16.7 heater path to GPIO low. */
|
||||
__writeMemory32(0x00000006, 0x40310584, "Memory");
|
||||
__writeMemory32(0x00000080, 0x40310804, "Memory");
|
||||
value = __readMemory32(0x403000B0, "Memory");
|
||||
__writeMemory32(value & 0xFFE0E0FF, 0x403000B0, "Memory");
|
||||
value = __readMemory32(0x40300104, "Memory");
|
||||
__writeMemory32(value & 0xE0FFFFFF, 0x40300104, "Memory");
|
||||
value = __readMemory32(0x403105C4, "Memory");
|
||||
__writeMemory32((value & 0xFFFFF00F) | 0x00000660,
|
||||
0x403105C4, "Memory");
|
||||
value = __readMemory32(0x40310844, "Memory");
|
||||
__writeMemory32((value & 0x0FFFFFFF) | 0x60000000,
|
||||
0x40310844, "Memory");
|
||||
__writeMemory32(0x00000006, 0x40310584, "Memory");
|
||||
__writeMemory32(0x00000080, 0x40310804, "Memory");
|
||||
|
||||
/* Preload IN1=P1.0, IN2/IN3=P5.4/P5.5 and IN4=P8.0 low. */
|
||||
__writeMemory32(0x00000001, 0x40310084, "Memory");
|
||||
__writeMemory32(0x00000030, 0x40310284, "Memory");
|
||||
__writeMemory32(0x00000001, 0x40310404, "Memory");
|
||||
|
||||
/* Select GPIO for every DRV8718 PWM input. */
|
||||
value = __readMemory32(0x40300010, "Memory");
|
||||
__writeMemory32(value & 0xFFFFFFE0, 0x40300010, "Memory");
|
||||
value = __readMemory32(0x40300054, "Memory");
|
||||
__writeMemory32(value & 0xFFFFE0E0, 0x40300054, "Memory");
|
||||
value = __readMemory32(0x40300080, "Memory");
|
||||
__writeMemory32(value & 0xFFFFE0E0, 0x40300080, "Memory");
|
||||
|
||||
/* Strong output, input buffer off (CY_GPIO_DM_STRONG_IN_OFF = 0x6). */
|
||||
value = __readMemory32(0x403100C4, "Memory");
|
||||
__writeMemory32((value & 0xFFFFFFF0) | 0x00000006,
|
||||
0x403100C4, "Memory");
|
||||
value = __readMemory32(0x403102C4, "Memory");
|
||||
__writeMemory32((value & 0xFF00FFFF) | 0x00660000,
|
||||
0x403102C4, "Memory");
|
||||
value = __readMemory32(0x40310444, "Memory");
|
||||
__writeMemory32((value & 0xFFFFFF00) | 0x00000066,
|
||||
0x40310444, "Memory");
|
||||
|
||||
/* Full drive strength for the same output pins. */
|
||||
value = __readMemory32(0x403100CC, "Memory");
|
||||
__writeMemory32(value & 0xFFFCFFFF, 0x403100CC, "Memory");
|
||||
value = __readMemory32(0x403102CC, "Memory");
|
||||
__writeMemory32(value & 0xF0FFFFFF, 0x403102CC, "Memory");
|
||||
value = __readMemory32(0x4031044C, "Memory");
|
||||
__writeMemory32(value & 0xFFF0FFFF, 0x4031044C, "Memory");
|
||||
|
||||
/* Reassert the final physical levels after mux/drive configuration. */
|
||||
__writeMemory32(0x00000001, 0x40310084, "Memory");
|
||||
__writeMemory32(0x00000030, 0x40310284, "Memory");
|
||||
__writeMemory32(0x00000001, 0x40310404, "Memory");
|
||||
__writeMemory32(0x00000002, 0x40310408, "Memory");
|
||||
|
||||
/* Verify the retained latch, every PWM counter, every PWM HSIOM field and
|
||||
every physical output latch before C-SPY releases the target. */
|
||||
safe = 1;
|
||||
value = __readMemory32(0x4027100C, "Memory");
|
||||
if(value != 0x4D4F5645)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40580600, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40580680, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40580700, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40580980, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40580A00, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40581E00, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40582080, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40310580, "Memory");
|
||||
if(value & 0x00000006)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40310800, "Memory");
|
||||
if(value & 0x00000080)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40300010, "Memory");
|
||||
if(value & 0x0000001F)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40300054, "Memory");
|
||||
if(value & 0x00001F1F)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40300080, "Memory");
|
||||
if(value & 0x00001F1F)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40310080, "Memory");
|
||||
if(value & 0x00000001)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40310280, "Memory");
|
||||
if(value & 0x00000030)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40310400, "Memory");
|
||||
if((value & 0x00000003) != 0x00000002)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
|
||||
if(safe == 0)
|
||||
{
|
||||
__message "Passenger_Seat_Timed_Controller_demo ERROR: C-SPY safe-off register verification failed.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
__message "Passenger_Seat_Timed_Controller_demo: C-SPY exit forced motor, fan and heater outputs low.\n";
|
||||
}
|
||||
}
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
/* C-SPY program-only safety hook used by the authorized backend flasher.
|
||||
* It forces every output safe but deliberately clears the debug-session
|
||||
* marker so --leave_target_running can boot normal firmware afterwards. */
|
||||
|
||||
execUserSetup()
|
||||
{
|
||||
__var value;
|
||||
|
||||
/* Make the pre-download target safe before the flash loader or the new
|
||||
application can run. The post-session block below repeats and verifies
|
||||
the same invariants when C-SPY reaches the normal exit hook. */
|
||||
__writeMemory32(0x00000002, 0x40310408, "Memory");
|
||||
value = __readMemory32(0x40580600, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580600, "Memory");
|
||||
value = __readMemory32(0x40580680, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580680, "Memory");
|
||||
value = __readMemory32(0x40580700, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580700, "Memory");
|
||||
value = __readMemory32(0x40580980, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580980, "Memory");
|
||||
value = __readMemory32(0x40580A00, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580A00, "Memory");
|
||||
value = __readMemory32(0x40581E00, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40581E00, "Memory");
|
||||
value = __readMemory32(0x40582080, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40582080, "Memory");
|
||||
__writeMemory32(0x00000001, 0x40310084, "Memory");
|
||||
__writeMemory32(0x00000030, 0x40310284, "Memory");
|
||||
__writeMemory32(0x00000001, 0x40310404, "Memory");
|
||||
__writeMemory32(0x00000006, 0x40310584, "Memory");
|
||||
__writeMemory32(0x00000080, 0x40310804, "Memory");
|
||||
|
||||
/* A new Download and Debug session releases a previous debug-exit latch. */
|
||||
__writeMemory32(0x00000000, 0x4027100C, "Memory");
|
||||
__message "Passenger_Seat_Timed_Controller_demo: C-SPY setup forced outputs safe and cleared the debug-session latch.\n";
|
||||
}
|
||||
|
||||
execUserExit()
|
||||
{
|
||||
__var value;
|
||||
__var safe;
|
||||
|
||||
/* This is a program-only session, not an interactive debugger detach. */
|
||||
__writeMemory32(0x00000000, 0x4027100C, "Memory");
|
||||
|
||||
/* Assert DRVOFF=P8.1 before touching PWM or pin muxing. */
|
||||
__writeMemory32(0x00000002, 0x40310408, "Memory");
|
||||
|
||||
/* Disable TCPWM1 group-0 counters IN1/IN2/IN3/IN4 and Hall timebase. */
|
||||
value = __readMemory32(0x40580600, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580600, "Memory");
|
||||
value = __readMemory32(0x40580680, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580680, "Memory");
|
||||
value = __readMemory32(0x40580700, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580700, "Memory");
|
||||
value = __readMemory32(0x40580980, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580980, "Memory");
|
||||
value = __readMemory32(0x40580A00, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40580A00, "Memory");
|
||||
|
||||
/* Disable fan TCPWM60 and heater TCPWM65 before changing their muxes. */
|
||||
value = __readMemory32(0x40581E00, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40581E00, "Memory");
|
||||
value = __readMemory32(0x40582080, "Memory");
|
||||
__writeMemory32(value & 0x7FFFFFFF, 0x40582080, "Memory");
|
||||
|
||||
/* Force P11.1/P11.2 fan paths and P16.7 heater path to GPIO low. */
|
||||
__writeMemory32(0x00000006, 0x40310584, "Memory");
|
||||
__writeMemory32(0x00000080, 0x40310804, "Memory");
|
||||
value = __readMemory32(0x403000B0, "Memory");
|
||||
__writeMemory32(value & 0xFFE0E0FF, 0x403000B0, "Memory");
|
||||
value = __readMemory32(0x40300104, "Memory");
|
||||
__writeMemory32(value & 0xE0FFFFFF, 0x40300104, "Memory");
|
||||
value = __readMemory32(0x403105C4, "Memory");
|
||||
__writeMemory32((value & 0xFFFFF00F) | 0x00000660,
|
||||
0x403105C4, "Memory");
|
||||
value = __readMemory32(0x40310844, "Memory");
|
||||
__writeMemory32((value & 0x0FFFFFFF) | 0x60000000,
|
||||
0x40310844, "Memory");
|
||||
__writeMemory32(0x00000006, 0x40310584, "Memory");
|
||||
__writeMemory32(0x00000080, 0x40310804, "Memory");
|
||||
|
||||
/* Preload IN1=P1.0, IN2/IN3=P5.4/P5.5 and IN4=P8.0 low. */
|
||||
__writeMemory32(0x00000001, 0x40310084, "Memory");
|
||||
__writeMemory32(0x00000030, 0x40310284, "Memory");
|
||||
__writeMemory32(0x00000001, 0x40310404, "Memory");
|
||||
|
||||
/* Select GPIO for every DRV8718 PWM input. */
|
||||
value = __readMemory32(0x40300010, "Memory");
|
||||
__writeMemory32(value & 0xFFFFFFE0, 0x40300010, "Memory");
|
||||
value = __readMemory32(0x40300054, "Memory");
|
||||
__writeMemory32(value & 0xFFFFE0E0, 0x40300054, "Memory");
|
||||
value = __readMemory32(0x40300080, "Memory");
|
||||
__writeMemory32(value & 0xFFFFE0E0, 0x40300080, "Memory");
|
||||
|
||||
/* Strong output, input buffer off (CY_GPIO_DM_STRONG_IN_OFF = 0x6). */
|
||||
value = __readMemory32(0x403100C4, "Memory");
|
||||
__writeMemory32((value & 0xFFFFFFF0) | 0x00000006,
|
||||
0x403100C4, "Memory");
|
||||
value = __readMemory32(0x403102C4, "Memory");
|
||||
__writeMemory32((value & 0xFF00FFFF) | 0x00660000,
|
||||
0x403102C4, "Memory");
|
||||
value = __readMemory32(0x40310444, "Memory");
|
||||
__writeMemory32((value & 0xFFFFFF00) | 0x00000066,
|
||||
0x40310444, "Memory");
|
||||
|
||||
/* Full drive strength for the same output pins. */
|
||||
value = __readMemory32(0x403100CC, "Memory");
|
||||
__writeMemory32(value & 0xFFFCFFFF, 0x403100CC, "Memory");
|
||||
value = __readMemory32(0x403102CC, "Memory");
|
||||
__writeMemory32(value & 0xF0FFFFFF, 0x403102CC, "Memory");
|
||||
value = __readMemory32(0x4031044C, "Memory");
|
||||
__writeMemory32(value & 0xFFF0FFFF, 0x4031044C, "Memory");
|
||||
|
||||
/* Reassert the final physical levels after mux/drive configuration. */
|
||||
__writeMemory32(0x00000001, 0x40310084, "Memory");
|
||||
__writeMemory32(0x00000030, 0x40310284, "Memory");
|
||||
__writeMemory32(0x00000001, 0x40310404, "Memory");
|
||||
__writeMemory32(0x00000002, 0x40310408, "Memory");
|
||||
|
||||
/* Verify the retained latch, every PWM counter, every PWM HSIOM field and
|
||||
every physical output latch before C-SPY releases the target. */
|
||||
safe = 1;
|
||||
value = __readMemory32(0x4027100C, "Memory");
|
||||
if(value != 0x00000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40580600, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40580680, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40580700, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40580980, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40580A00, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40581E00, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40582080, "Memory");
|
||||
if(value & 0x80000000)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40310580, "Memory");
|
||||
if(value & 0x00000006)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40310800, "Memory");
|
||||
if(value & 0x00000080)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40300010, "Memory");
|
||||
if(value & 0x0000001F)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40300054, "Memory");
|
||||
if(value & 0x00001F1F)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40300080, "Memory");
|
||||
if(value & 0x00001F1F)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40310080, "Memory");
|
||||
if(value & 0x00000001)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40310280, "Memory");
|
||||
if(value & 0x00000030)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
value = __readMemory32(0x40310400, "Memory");
|
||||
if((value & 0x00000003) != 0x00000002)
|
||||
{
|
||||
safe = 0;
|
||||
}
|
||||
|
||||
if(safe == 0)
|
||||
{
|
||||
__message "Passenger_Seat_Timed_Controller_demo ERROR: C-SPY safe-off register verification failed.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
__message "Passenger_Seat_Timed_Controller_demo: program-only exit forced all outputs low and released the debug latch.\n";
|
||||
}
|
||||
}
|
||||
+2690
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
@@ -0,0 +1,109 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import unittest
|
||||
import xml.etree.ElementTree as ET
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
EWP = ROOT / "IAR" / "Passenger_Seat_Timed_Controller_demo.ewp"
|
||||
APP = ROOT / "App" / "seat_timed_application.c"
|
||||
CAN_BSP = ROOT / "Bsp" / "bsp_seat_move_can.c"
|
||||
CONFIG = ROOT / "Config" / "seat_move_config.h"
|
||||
|
||||
|
||||
class TimedOnlyFirmwareAudit(unittest.TestCase):
|
||||
def test_iar_project_is_valid_xml_and_local_references_exist(self) -> None:
|
||||
tree = ET.parse(EWP)
|
||||
project_dir = EWP.parent
|
||||
missing: list[str] = []
|
||||
for element in tree.findall(".//file/name"):
|
||||
value = element.text or ""
|
||||
if not value.startswith("$PROJ_DIR$"):
|
||||
continue
|
||||
relative = value.removeprefix("$PROJ_DIR$\\").replace("\\", "/")
|
||||
if not (project_dir / relative).resolve().is_file():
|
||||
missing.append(value)
|
||||
self.assertEqual([], missing)
|
||||
|
||||
def test_iar_target_declares_timed_only_and_excludes_other_apps(self) -> None:
|
||||
text = EWP.read_text(encoding="utf-8")
|
||||
self.assertIn("PASSENGER_SEAT_TIMED_ONLY=1", text)
|
||||
self.assertIn("seat_timed_application.c", text)
|
||||
self.assertIn("Passenger_Seat_Timed_Controller_demo.hex", text)
|
||||
for forbidden in (
|
||||
"seat_move_application",
|
||||
"seat_dynamic_mode",
|
||||
"seat_move_store",
|
||||
"seat_controller_thermal",
|
||||
"..\\App\\seat_backrest_heater.c</name>",
|
||||
"bsp_seat_backrest_heater_adc",
|
||||
):
|
||||
self.assertNotIn(forbidden, text)
|
||||
|
||||
def test_can_hardware_filter_accepts_only_command_id(self) -> None:
|
||||
text = CAN_BSP.read_text(encoding="utf-8")
|
||||
block = re.search(
|
||||
r"s_standardIdFilters\[\]\s*=\s*\{(?P<body>.*?)\};",
|
||||
text,
|
||||
re.DOTALL,
|
||||
)
|
||||
self.assertIsNotNone(block)
|
||||
body = block.group("body")
|
||||
self.assertEqual(2, body.count("SEAT_MOVE_CAN_COMMAND_ID"))
|
||||
self.assertNotRegex(body, r"0x(?:29E|2AA|3CE|42A|2F0)u")
|
||||
self.assertNotIn("HIL_SELF_HEAL", body)
|
||||
|
||||
def test_application_exposes_only_timed_motion_dispatch(self) -> None:
|
||||
text = APP.read_text(encoding="utf-8")
|
||||
self.assertIn("SeatMotor_MoveTimedDuty", text)
|
||||
for forbidden_call in (
|
||||
"SeatMotor_MoveAbsolute",
|
||||
"SeatMotor_MoveRelative",
|
||||
"SeatMotor_CalibrateRange",
|
||||
"SeatMotor_HomeKnownRange",
|
||||
"SeatDynamicMode_",
|
||||
"SeatMoveStore_",
|
||||
"SeatControllerThermal_",
|
||||
):
|
||||
self.assertNotIn(forbidden_call, text)
|
||||
|
||||
accepted = set(
|
||||
re.findall(
|
||||
r"case\s+(SEAT_TIMED_OPCODE_[A-Z_]+)\s*:",
|
||||
text[text.index("static bool SeatTimed_ParseCommand") :
|
||||
text.index("static bool SeatTimed_ParametersValid")],
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
{
|
||||
"SEAT_TIMED_OPCODE_MOVE_TIMED",
|
||||
"SEAT_TIMED_OPCODE_STOP_MOTOR",
|
||||
"SEAT_TIMED_OPCODE_STOP_ALL",
|
||||
"SEAT_TIMED_OPCODE_QUERY_STATUS",
|
||||
"SEAT_TIMED_OPCODE_CLEAR_FAULT",
|
||||
},
|
||||
accepted,
|
||||
)
|
||||
|
||||
def test_axis_specific_duration_limits_are_present(self) -> None:
|
||||
text = CONFIG.read_text(encoding="utf-8")
|
||||
expected = {
|
||||
"SEAT_TIMED_MIN_DURATION_MS": "300",
|
||||
"SEAT_TIMED_M0_MAX_DURATION_MS": "30000",
|
||||
"SEAT_TIMED_M1_MAX_DURATION_MS": "20000",
|
||||
"SEAT_TIMED_M2_MAX_DURATION_MS": "30000",
|
||||
"SEAT_TIMED_M3_MAX_DURATION_MS": "25000",
|
||||
}
|
||||
for name, value in expected.items():
|
||||
self.assertRegex(
|
||||
text,
|
||||
rf"#define\s+{name}\s+\({value}u\)",
|
||||
)
|
||||
self.assertNotIn("SEAT_MOVE_CAN_DYNAMIC_STATUS_ID", text)
|
||||
self.assertNotIn("SEAT_MOVE_CAN_HIL_SELF_HEAL_REQUEST_ID", text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(verbosity=2)
|
||||
+10
-2
@@ -2,7 +2,14 @@
|
||||
|
||||
`Seat_Controller_demo/` is the repository-owned IAR project used by the real
|
||||
seat-bench executor. It contains the 2026-07-30 heater, ventilation, four-axis
|
||||
motion, SMV8 position memory, Hall feedback and ADC current-diagnostic code.
|
||||
time/position motion, SMV8 position memory, Hall feedback and ADC
|
||||
current-diagnostic code.
|
||||
|
||||
`Passenger_Seat_Timed_Controller_demo/` is the separately buildable
|
||||
passenger-seat variant. Its CAN application exposes four-axis timed movement
|
||||
only; position, homing, calibration, dynamic-mode and thermal commands are not
|
||||
linked into the application. See its `Docs/README_Passenger_Seat_Timed_Controller.md`
|
||||
for the command contract and generated HEX identity (`PST1`).
|
||||
|
||||
The matching Cypress 7.9.0 build dependencies are vendored beside it:
|
||||
|
||||
@@ -10,7 +17,8 @@ The matching Cypress 7.9.0 build dependencies are vendored beside it:
|
||||
firmware/t2g/
|
||||
├── common/
|
||||
├── tviibh8m/
|
||||
└── Seat_Controller_demo/
|
||||
├── Seat_Controller_demo/
|
||||
└── Passenger_Seat_Timed_Controller_demo/
|
||||
```
|
||||
|
||||
This preserves the IAR project's `../../common` and `../../tviibh8m` paths and
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "bsp_seat_backrest_heater.h"
|
||||
#include "bsp_seat_fan.h"
|
||||
#include "seat_controller_thermal.h"
|
||||
#include "seat_feature_profile.h"
|
||||
|
||||
volatile uint32_t g_seatMoveResetReason = 0u;
|
||||
volatile uint32_t g_seatMoveInitResult = MOTOR_API_FAILURE;
|
||||
@@ -59,11 +60,13 @@ int main(void)
|
||||
}
|
||||
|
||||
Motor_SetWatchdogServiceEnabled(true);
|
||||
#if SEAT_FEATURE_THERMAL
|
||||
if(!SeatControllerThermal_Init())
|
||||
{
|
||||
SafetyManager_LatchFault(SAFETY_FAULT_DRIVER);
|
||||
SeatMove_HoldSafeOff();
|
||||
}
|
||||
#endif
|
||||
if(!SeatMoveApplication_Init())
|
||||
{
|
||||
SeatMove_HoldSafeOff();
|
||||
@@ -72,7 +75,9 @@ int main(void)
|
||||
for(;;)
|
||||
{
|
||||
SeatMoveApplication_Service();
|
||||
#if SEAT_FEATURE_THERMAL
|
||||
SeatControllerThermal_Service1ms();
|
||||
#endif
|
||||
if(SafetyManager_IsInhibited())
|
||||
{
|
||||
Motor_ForceSafeOff();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "seat_backrest_heater.h"
|
||||
#include "seat_backrest_heater_config.h"
|
||||
#include "seat_fan_config.h"
|
||||
#include "seat_feature_profile.h"
|
||||
|
||||
#define SEAT_CONTROLLER_THERMAL_CONTROL_ID (0x29Eu)
|
||||
#define SEAT_CONTROLLER_THERMAL_CONFIG_ID (0x2AAu)
|
||||
@@ -247,6 +248,7 @@ static void SeatControllerThermal_HandleControl29e(
|
||||
fanGear = (uint8_t)((frame->data0 >> 16u) & 0x0Fu);
|
||||
heaterGear = (uint8_t)((frame->data0 >> 20u) & 0x0Fu);
|
||||
|
||||
#if SEAT_FEATURE_VENTILATION
|
||||
if(fanOn == 2u)
|
||||
{
|
||||
SeatControllerThermal_StopFan(1u);
|
||||
@@ -266,7 +268,14 @@ static void SeatControllerThermal_HandleControl29e(
|
||||
g_seatControllerThermalInvalidCount++;
|
||||
SeatControllerThermal_StopFan(0u);
|
||||
}
|
||||
#else
|
||||
(void)fanOn;
|
||||
(void)fanMode;
|
||||
(void)fanGear;
|
||||
SeatControllerThermal_StopFan(1u);
|
||||
#endif
|
||||
|
||||
#if SEAT_FEATURE_HEATING
|
||||
if(heaterOn == 2u)
|
||||
{
|
||||
SeatControllerThermal_StopHeater(1u);
|
||||
@@ -286,6 +295,11 @@ static void SeatControllerThermal_HandleControl29e(
|
||||
g_seatControllerThermalInvalidCount++;
|
||||
SeatControllerThermal_StopHeater(0u);
|
||||
}
|
||||
#else
|
||||
(void)heaterOn;
|
||||
(void)heaterGear;
|
||||
SeatControllerThermal_StopHeater(1u);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void SeatControllerThermal_HandleConfig2aa(
|
||||
@@ -308,16 +322,23 @@ static void SeatControllerThermal_HandleConfig2aa(
|
||||
g_seatControllerThermalInvalidCount++;
|
||||
return;
|
||||
}
|
||||
#if SEAT_FEATURE_VENTILATION
|
||||
s_fanConfiguredMaxGear = (fanConfig == 1u) ? 1u :
|
||||
((fanConfig == 2u) ? 2u : 3u);
|
||||
#endif
|
||||
#if SEAT_FEATURE_HEATING
|
||||
s_heaterConfiguredMaxLevel = (heaterConfig == 1u) ? 1u :
|
||||
((heaterConfig == 2u) ? 2u : 3u);
|
||||
#endif
|
||||
#if SEAT_FEATURE_VENTILATION
|
||||
if(s_fanRunning &&
|
||||
!SeatControllerThermal_RequestFan(s_fanLastVehicleGear))
|
||||
{
|
||||
g_seatControllerThermalOutputFaultStage = 4u;
|
||||
SeatControllerThermal_LatchOutputFault();
|
||||
}
|
||||
#endif
|
||||
#if SEAT_FEATURE_HEATING
|
||||
if(g_seatBackrestHeaterAppliedLevel !=
|
||||
SEAT_BACKREST_HEATER_LEVEL_OFF)
|
||||
{
|
||||
@@ -327,11 +348,13 @@ static void SeatControllerThermal_HandleConfig2aa(
|
||||
SeatControllerThermal_LatchOutputFault();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void SeatControllerThermal_HandleMode3ce(
|
||||
const bsp_seat_move_can_frame_t *frame)
|
||||
{
|
||||
#if SEAT_FEATURE_HEATING
|
||||
uint8_t mode;
|
||||
if(frame->dlc != SEAT_FAN_CAN_DLC)
|
||||
{
|
||||
@@ -347,6 +370,10 @@ static void SeatControllerThermal_HandleMode3ce(
|
||||
g_seatControllerThermalInvalidCount++;
|
||||
SeatControllerThermal_StopHeater(0u);
|
||||
}
|
||||
#else
|
||||
(void)frame;
|
||||
SeatControllerThermal_StopHeater(1u);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void SeatControllerThermal_HandleSwitch42a(
|
||||
@@ -363,6 +390,7 @@ static void SeatControllerThermal_HandleSwitch42a(
|
||||
}
|
||||
fanSwitch = (uint8_t)(frame->data0 & 0x03u);
|
||||
heaterSwitch = (uint8_t)((frame->data0 >> 2u) & 0x03u);
|
||||
#if SEAT_FEATURE_VENTILATION
|
||||
if(fanSwitch == 1u)
|
||||
{
|
||||
if(!SeatControllerThermal_RequestFan(s_fanLastVehicleGear))
|
||||
@@ -375,6 +403,11 @@ static void SeatControllerThermal_HandleSwitch42a(
|
||||
{
|
||||
SeatControllerThermal_StopFan(1u);
|
||||
}
|
||||
#else
|
||||
(void)fanSwitch;
|
||||
SeatControllerThermal_StopFan(1u);
|
||||
#endif
|
||||
#if SEAT_FEATURE_HEATING
|
||||
if(heaterSwitch == 1u)
|
||||
{
|
||||
if(!SeatControllerThermal_RequestHeater(s_heaterLastVehicleGear))
|
||||
@@ -387,10 +420,15 @@ static void SeatControllerThermal_HandleSwitch42a(
|
||||
{
|
||||
SeatControllerThermal_StopHeater(1u);
|
||||
}
|
||||
#else
|
||||
(void)heaterSwitch;
|
||||
SeatControllerThermal_StopHeater(1u);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool SeatControllerThermal_RequestFan(uint8_t vehicleGear)
|
||||
{
|
||||
#if SEAT_FEATURE_VENTILATION
|
||||
uint8_t physicalGear = (vehicleGear >= 3u) ? 3u : vehicleGear;
|
||||
if((vehicleGear == 0u) || (vehicleGear > 5u))
|
||||
{
|
||||
@@ -418,10 +456,15 @@ static bool SeatControllerThermal_RequestFan(uint8_t vehicleGear)
|
||||
return BspSeatFan_SetDutyPercent(s_fanTargetDutyPercent);
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
(void)vehicleGear;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool SeatControllerThermal_RequestHeater(uint8_t vehicleGear)
|
||||
{
|
||||
#if SEAT_FEATURE_HEATING
|
||||
uint8_t physicalLevel = (vehicleGear >= 3u) ? 3u : vehicleGear;
|
||||
if((vehicleGear == 0u) || (vehicleGear > 5u) || !s_heaterModeValid)
|
||||
{
|
||||
@@ -440,6 +483,10 @@ static bool SeatControllerThermal_RequestHeater(uint8_t vehicleGear)
|
||||
g_seatControllerHeaterFeedbackRaw = physicalLevel + 1u;
|
||||
s_feedbackPending = true;
|
||||
return true;
|
||||
#else
|
||||
(void)vehicleGear;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void SeatControllerThermal_StopFan(uint8_t feedbackRaw)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "safety_manager.h"
|
||||
#include "seat_controller_thermal.h"
|
||||
#include "seat_dynamic_mode.h"
|
||||
#include "seat_feature_profile.h"
|
||||
#include "seat_motor_manager.h"
|
||||
#include "seat_move_config.h"
|
||||
#include "seat_move_store.h"
|
||||
@@ -336,7 +337,9 @@ void SeatMoveApplication_Service(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if SEAT_FEATURE_THERMAL
|
||||
SeatControllerThermal_HandleFrame(&frame);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
SeatMove_ServiceDispatcher();
|
||||
@@ -363,7 +366,9 @@ void Motor_CalibrationServiceHook(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if SEAT_FEATURE_THERMAL
|
||||
SeatControllerThermal_HandleFrame(&frame);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if(g_bspSeatMoveCanBusOff != 0u)
|
||||
@@ -533,15 +538,28 @@ static bool SeatMove_ParseCommand(const bsp_seat_move_can_frame_t *frame,
|
||||
{
|
||||
case SEAT_MOVE_OPCODE_MOVE_ABSOLUTE:
|
||||
case SEAT_MOVE_OPCODE_MOVE_RELATIVE:
|
||||
#if SEAT_FEATURE_POSITION_CONTROL
|
||||
break;
|
||||
#else
|
||||
*reject = SEAT_MOVE_REJECT_BAD_OPCODE;
|
||||
return false;
|
||||
#endif
|
||||
case SEAT_MOVE_OPCODE_MOVE_TIMED:
|
||||
case SEAT_MOVE_OPCODE_STOP_MOTOR:
|
||||
case SEAT_MOVE_OPCODE_STOP_ALL:
|
||||
break;
|
||||
case SEAT_MOVE_OPCODE_CALIBRATE_RANGE:
|
||||
case SEAT_MOVE_OPCODE_HOME_KNOWN_RANGE:
|
||||
case SEAT_MOVE_OPCODE_QUERY_STATUS:
|
||||
case SEAT_MOVE_OPCODE_CLEAR_FAULT:
|
||||
case SEAT_MOVE_OPCODE_START_DYNAMIC_MODE:
|
||||
case SEAT_MOVE_OPCODE_STOP_DYNAMIC_MODE:
|
||||
#if SEAT_FEATURE_POSITION_CONTROL
|
||||
break;
|
||||
#else
|
||||
*reject = SEAT_MOVE_REJECT_BAD_OPCODE;
|
||||
return false;
|
||||
#endif
|
||||
case SEAT_MOVE_OPCODE_QUERY_STATUS:
|
||||
case SEAT_MOVE_OPCODE_CLEAR_FAULT:
|
||||
break;
|
||||
default:
|
||||
*reject = SEAT_MOVE_REJECT_BAD_OPCODE;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef SEAT_FEATURE_PROFILE_H
|
||||
#define SEAT_FEATURE_PROFILE_H
|
||||
|
||||
/*
|
||||
* Repository default is the complete controller. The workbench build script
|
||||
* replaces this header only inside its isolated staging tree so every OTA
|
||||
* task receives the exact capability profile selected by the user.
|
||||
*/
|
||||
#define SEAT_FEATURE_POSITION_CONTROL (1)
|
||||
#define SEAT_FEATURE_VENTILATION (1)
|
||||
#define SEAT_FEATURE_HEATING (1)
|
||||
|
||||
#if ((SEAT_FEATURE_POSITION_CONTROL != 0) && \
|
||||
(SEAT_FEATURE_POSITION_CONTROL != 1))
|
||||
#error "SEAT_FEATURE_POSITION_CONTROL must be 0 or 1"
|
||||
#endif
|
||||
#if ((SEAT_FEATURE_VENTILATION != 0) && (SEAT_FEATURE_VENTILATION != 1))
|
||||
#error "SEAT_FEATURE_VENTILATION must be 0 or 1"
|
||||
#endif
|
||||
#if ((SEAT_FEATURE_HEATING != 0) && (SEAT_FEATURE_HEATING != 1))
|
||||
#error "SEAT_FEATURE_HEATING must be 0 or 1"
|
||||
#endif
|
||||
|
||||
#define SEAT_FEATURE_THERMAL \
|
||||
((SEAT_FEATURE_VENTILATION != 0) || (SEAT_FEATURE_HEATING != 0))
|
||||
|
||||
#endif /* SEAT_FEATURE_PROFILE_H */
|
||||
@@ -2359,6 +2359,9 @@
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\Config\seat_move_config.h</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\Config\seat_feature_profile.h</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\Config\seat_backrest_heater_config.h</name>
|
||||
</file>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
:020000041000EA
|
||||
:100000000000022801EC00103DF4001055F1001032
|
||||
:1000000000000228F5EB0010E1F30010F9F00010F9
|
||||
:1000100000000000000000000000000000000000E0
|
||||
:1000200000000000000000000000000015F20010B9
|
||||
:10003000000000000000000041F4001045F4001032
|
||||
:10002000000000000000000000000000B9F1001016
|
||||
:100030000000000000000000E5F30010E9F30010EC
|
||||
:10004000CDE50010F1E5001015E6001039E60010CE
|
||||
:100050005DE6001081E60010A5E60010C9E600107C
|
||||
:1000600049F400104DF4001051F4001055F4001044
|
||||
:1000700059F400105DF4001061F4001065F40010F4
|
||||
:10006000EDF30010F1F30010F5F30010F9F30010B8
|
||||
:10007000FDF3001001F4001005F4001009F4001065
|
||||
:1000800000B5010009B2002905D40121C006C00E47
|
||||
:100090008140C648016000BD00B5010009B20029D9
|
||||
:1000A00005D40121C006C00E8140C148016000BDD9
|
||||
@@ -78,7 +78,7 @@
|
||||
:1004C000060091204000FFF779FFF106C90E009168
|
||||
:1004D00071090B051B0D5B1E2200D2B20321C0B2B5
|
||||
:1004E000FFF7F8FED3BD80B51300A74A13600023C1
|
||||
:1004F000137203F048FE01BD24F3001000B5C0B232
|
||||
:1004F000137203F048FE01BDC8F2001000B5C0B28F
|
||||
:10050000042801D2012000E00020C0B200BD00B5E7
|
||||
:10051000401A00B2012801DB012000E00020C0B237
|
||||
:1005200000BD00B5BE490978002901D000201FE0B8
|
||||
@@ -313,8 +313,8 @@
|
||||
:101370002000FFF723F801220321C0B2FFF762F833
|
||||
:10138000884C200003F0A2FE00228749200003F0D1
|
||||
:1013900063FD2000FEF720FF13BD0000FC1B0028AA
|
||||
:1013A00034E700108CEB0010C21C00283CEE00104B
|
||||
:1013B0002CF30010CD100010F2B5060000273C0001
|
||||
:1013A00034E7001080EB0010C21C0028B8EC0010DD
|
||||
:1013B000D0F20010CD100010F2B5060000273C005E
|
||||
:1013C0000098002801D1002077E0380000990880BB
|
||||
:1013D00003F0AEFBCD490978002903D003F0ACFB44
|
||||
:1013E00000206AE00121C94A117003F0A5FB6D4D90
|
||||
@@ -343,9 +343,9 @@
|
||||
:10155000FFF7D5FF002806D068460078E4B2A04225
|
||||
:1015600001D1012000E00020C0B232BD80B5B44AF4
|
||||
:1015700000211160017C1172C168806802F003FED5
|
||||
:1015800001BD00006012002808F00010000658405D
|
||||
:1015800001BD000060120028ACEF001000065840BA
|
||||
:1015900080065840000758408009584000B4C404F1
|
||||
:1015A0000024F400000064408CEE0010F8B5012621
|
||||
:1015A0000024F4000000644030EE0010F8B501267D
|
||||
:1015B0003000002468460470564804700121A14898
|
||||
:1015C000FEF7B8FDC24F01213800FEF7B3FD9E4D76
|
||||
:1015D000280003F003FE01219C48FEF7ABFD280024
|
||||
@@ -1109,12 +1109,12 @@
|
||||
:104530009BB21B0A9BB2174C14401B02FF221202B3
|
||||
:104540001A4022430B78052B05D10979C9B2FF2304
|
||||
:104550009A43114304E04978FF239A43C9B21143B7
|
||||
:10456000016300221000F2BD0CF40010FFFFFBFFFE
|
||||
:10456000016300221000F2BDB0F30010FFFFFBFF5B
|
||||
:10457000FFFFFCFFFFFFFFF8FFFFFFBFFFFBFFFF99
|
||||
:10458000FFFDFFFFFFFEFFFFFFCFFFFF10F4001056
|
||||
:10459000FFFF00FFFF00FFFF14F4001018F40010ED
|
||||
:1045A000FFF3FFFFFFFCFFFF1CF4001020F40010DE
|
||||
:1045B00024F400100168802212060A43026070474A
|
||||
:10458000FFFDFFFFFFFEFFFFFFCFFFFFB4F30010B3
|
||||
:10459000FFFF00FFFF00FFFFB8F30010BCF30010A7
|
||||
:1045A000FFF3FFFFFFFCFFFFC0F30010C4F3001098
|
||||
:1045B000C8F300100168802212060A4302607047A7
|
||||
:1045C000016849004908016070474068704701610F
|
||||
:1045D00070470069704781607047006A704700004B
|
||||
:1045E00030B4434351435D18010C0C00130C5C4381
|
||||
@@ -1169,7 +1169,7 @@
|
||||
:1048F000142060432818007C787103A914206043B9
|
||||
:104900002818C06802F0EAFC0028E7D0300002F066
|
||||
:10491000E1FC002003E0012071490870012019B07A
|
||||
:10492000F0BD000024F3001000000440FF00FFFF72
|
||||
:10492000F0BD0000C8F2001000000440FF00FFFFCF
|
||||
:10493000FF0000FFF8B584B00E00C0B20290002561
|
||||
:1049400028006946088004212A0003AC200002F0F8
|
||||
:1049500033FC2C0062480078002806D0674F387876
|
||||
@@ -1191,16 +1191,16 @@
|
||||
:104A500001D0002018E0631E042201212800FFF786
|
||||
:104A6000EFFD002801D000200EE0042201212800E3
|
||||
:104A7000FFF771FE002801D0002005E0009821001A
|
||||
:104A8000FFF7C0FB38600120F2BD0000FCF200100F
|
||||
:104A8000FFF7C0FB38600120F2BD0000A0F200106B
|
||||
:104A90007CB505001D4C062100226E46300002F058
|
||||
:104AA0008BFB6946280002F011FE6846007800285A
|
||||
:104AB00003D1641E002CF4D101E0012000E00020AD
|
||||
:104AC00076BD000014F10010E0B511490CC9083999
|
||||
:104AC00076BD0000B8F00010E0B511490CC90839F6
|
||||
:104AD00069460CC10839694602F0A2FD07BD000015
|
||||
:104AE000B71C0028901B0028A81B00282CEA0010E7
|
||||
:104AE000B71C0028901B0028A81B002820EA0010F3
|
||||
:104AF000FFC99A3B00CA9A3B00109040B81C00289E
|
||||
:104B00005F8DCB00608DCB0001000100A08601000D
|
||||
:104B100004F300100000000000000000000000008E
|
||||
:104B1000A8F20010000000000000000000000000EB
|
||||
:104B2000801C800803D0401C801EFCD100BF704751
|
||||
:104B3000EFF3108072B6704780F3108870474030F2
|
||||
:104B4000016810220A430260704740300168082261
|
||||
@@ -1234,10 +1234,10 @@
|
||||
:104D0000A54394000C2222402A43C264174A146827
|
||||
:104D10004C228A5C1A400725AC4322434D240C5D8B
|
||||
:104D200023407024A2431C01702323401343436596
|
||||
:104D3000497D816700221000F2BD0000F8F30010E9
|
||||
:104D3000497D816700221000F2BD00009CF3001045
|
||||
:104D4000FFFFFBFFFFFFFCFFFFFFFFF8FFFFFFBFC1
|
||||
:104D5000FCF30010FFFF00FFFF00FFFF00F4001056
|
||||
:104D600004F40010FFF3FFFFFFFCFFFF08F4001046
|
||||
:104D5000A0F30010FFFF00FFFF00FFFFA4F300100F
|
||||
:104D6000A8F30010FFF3FFFFFFFCFFFFACF3001000
|
||||
:104D70000168802212060A43026070477830016899
|
||||
:104D800001220A4302607047C16F0800C007C00FCC
|
||||
:104D90007047010070310A68012313430B60006FF4
|
||||
@@ -1246,7 +1246,7 @@
|
||||
:104DC0000B79002B01D00122FFE763005B08D207BB
|
||||
:104DD0001A430B4B0024095F89005A5000E0064833
|
||||
:104DE00030BD00B5074A1368002B03D0126800B22B
|
||||
:104DF0008000115000BD000001005600F4F30010C7
|
||||
:104DF0008000115000BD00000100560098F3001023
|
||||
:104E0000008020402412002870B4103A03D378C9DF
|
||||
:104E1000103A78C0FBD2530701D318C918C001D586
|
||||
:104E200008C908C0D20704D30B880380891C801CE2
|
||||
@@ -1296,8 +1296,8 @@
|
||||
:1050E0000021C1239B00C15080239B00C25081221C
|
||||
:1050F00092008150124A8150154A8150114A8150C4
|
||||
:10510000114A8150134A8150134A81507047000060
|
||||
:105110000140AA00DCF30010E0F30010E4F30010FB
|
||||
:10512000E8F30010FF3FFFFFFFFEFFFFFFFFFFFC64
|
||||
:105110000140AA0080F3001084F3001088F300100F
|
||||
:105120008CF30010FF3FFFFFFFFEFFFFFFFFFFFCC0
|
||||
:10513000FFFDFFFFFFFBFFFFFFF7FFFF0F00000377
|
||||
:10514000C80E0000C80F0000880F0000EFCDAB00B4
|
||||
:10515000880E0000080F0000480F0000F8B504009A
|
||||
@@ -1313,7 +1313,7 @@
|
||||
:1051F00002F0DAFE0020E075E52040000A49086070
|
||||
:10520000002002F031FF2C0030681049FEF7FAFF51
|
||||
:10521000002122000023FFF7E3F9FFF79FFF70BD95
|
||||
:10522000181B00288CED0010F01B002810E000E097
|
||||
:10522000181B0028A0ED0010F01B002810E000E083
|
||||
:10523000BE1C0028FFFFFF00010000FFFFFFFFFF73
|
||||
:1052400014E000E0941C002818E000E040420F0049
|
||||
:1052500043490A680860704742490A680860704715
|
||||
@@ -1402,8 +1402,8 @@
|
||||
:1057800000B5114B1870114B1970002A05D0117813
|
||||
:105790000F4B197091880F4A1180C0B2002803D0B6
|
||||
:1057A00001209949087002E0002097490870012003
|
||||
:1057B0009649087000BD0000AC1A002834F40010AF
|
||||
:1057C000D0F2001038F40010D71C0028D81C002894
|
||||
:1057B0009649087000BD0000AC1A0028D8F300100C
|
||||
:1057C00074F20010DCF30010D71C0028D81C00284D
|
||||
:1057D000D91C0028B01C0028F8B50500002D05D004
|
||||
:1057E0000C00002C02D01600002E01D1002039E060
|
||||
:1057F0000A2100222700380001F0DEFC68682070D2
|
||||
@@ -1866,7 +1866,7 @@
|
||||
:107480009205C02000041040084300998860E08AFB
|
||||
:10749000390C090480B20843218B82B208041043DE
|
||||
:1074A0000099C86021001A31009800F055F801E0F9
|
||||
:1074B00020480190019805B0F0BD00004CF3001089
|
||||
:1074B00020480190019805B0F0BD0000F0F20010E6
|
||||
:1074C000FFFEFFFFFFFDFFFFFFFBFFFFFFFFFFDFF3
|
||||
:1074D0003830016801220A43026070473830016881
|
||||
:1074E00001229143016070473C30016801220A4348
|
||||
@@ -1874,8 +1874,8 @@
|
||||
:1075000014D05B6A1C000C80190F0C00E407E40F18
|
||||
:107510001470990F0C00E407E40F9470590F0C00DD
|
||||
:10752000E407E40F5470D90FD17000E0014810BD9A
|
||||
:10753000FFFFFFBF0100DA0050F3001054F300100A
|
||||
:1075400058F300105CF3001060F30010FFFCFFFF25
|
||||
:10753000FFFFFFBF0100DA00F4F20010F8F20010C4
|
||||
:10754000FCF2001000F3001004F30010FFFCFFFF3A
|
||||
:10755000FFF7FFFFFFF8FFFFF0B50A000023190057
|
||||
:107560006F4C2468002A49D05579002D01D001269E
|
||||
:1075700000E01E006B4D2540B4028026F60034402A
|
||||
@@ -1905,8 +1905,8 @@
|
||||
:1076F000E407E40FCC7053081C00E407E40F4C705F
|
||||
:1077000013001C00E407E40F0C7092081300DB0761
|
||||
:10771000DB0F8B7000E0014810BD00000100DA00B3
|
||||
:1077200064F30010FFFBFFFFFFFDFFFFFFFEFFFF05
|
||||
:1077300068F3001000B5012027490A68520802408A
|
||||
:1077200008F30010FFFBFFFFFFFDFFFFFFFEFFFF61
|
||||
:107730000CF3001000B5012027490A6852080240E6
|
||||
:10774000002A01D0022001E00968084000BD274856
|
||||
:1077500001680800C007C00F704700B5C21E022AAA
|
||||
:1077600001D3012002E0C01E0860002000BD1CB54E
|
||||
@@ -1929,7 +1929,7 @@
|
||||
:107870008007800F32BD0000401626400F48006888
|
||||
:10788000000AC0B270470E480068000AC0B27047D4
|
||||
:10789000000000000019264010002740181B002897
|
||||
:1078A000D4EC00105B080000F01B002840122640BA
|
||||
:1078A00008ED00105B080000F01B00284012264085
|
||||
:1078B00004480068000AC0B2704700001010204061
|
||||
:1078C0000C1020400810204038B50400072C0ED3BF
|
||||
:1078D000124D18221249280000F066FB0020E875BE
|
||||
@@ -1937,7 +1937,7 @@
|
||||
:1078F000A10040584007400F010009B2042907D1F8
|
||||
:107900000448A1004058C106C90E80204000084329
|
||||
:1079100000B232BD0001264000122640181B00288C
|
||||
:1079200030ED0010F01B00281E4909688A03920BF5
|
||||
:1079200054ED0010F01B00281E4909688A03920BD1
|
||||
:107930000260090E0A00D207D20FC2711749096806
|
||||
:107940000A00D204D20C82800A00120CD2B2028148
|
||||
:10795000090CC9B24181264909680F220B00134066
|
||||
@@ -2030,7 +2030,7 @@
|
||||
:107EC000002805D002280BD006D303280CD00FE0E1
|
||||
:107ED00000982860002032BD009840082860F9E72B
|
||||
:107EE000009880082860F5E70098C0082860F1E74E
|
||||
:107EF000002028600320EEE7181B002830ED00105A
|
||||
:107EF000002028600320EEE7181B002854ED001036
|
||||
:107F000063090000F01B0028001626407F090000CE
|
||||
:107F1000001926401CB5040069460020FFF7AFFF9A
|
||||
:107F20000100C9B2002903D000212160C0B209E0DC
|
||||
@@ -2352,7 +2352,7 @@
|
||||
:1092E0000C482A00D2B2805CFFF724FE002808D088
|
||||
:1092F00068463221405C002803D020000124AC40A5
|
||||
:1093000004436D1C2800C0B20428E8D32000C0B27A
|
||||
:109310000FB030BD28F40010C027090000B5017857
|
||||
:109310000FB030BDCCF30010C027090000B50178B4
|
||||
:109320000A290ED0417804290BD04178062908D0AB
|
||||
:109330004178072905D04178082902D040780928CA
|
||||
:1093400001D1012000E00020C0B200BDF1B590B015
|
||||
@@ -2378,7 +2378,7 @@
|
||||
:10948000691848832B895A2270682100C9B24900A3
|
||||
:10949000415A8B482700FFB2C05DFFF719FC002836
|
||||
:1094A000E1D1002000E00120F2BD0000FFFF00003C
|
||||
:1094B0009CF00010781A0028F8B590B00700002F33
|
||||
:1094B00040F00010781A0028F8B590B00700002F8F
|
||||
:1094C00004D008003B7BC0B2984201D30020BEE02C
|
||||
:1094D000B8680B00DBB218246343C0180190904EAB
|
||||
:1094E00002207070F17001980078B07032610198BC
|
||||
@@ -2411,13 +2411,13 @@
|
||||
:10969000641C2000C0B2042810D22B89B27D2000A7
|
||||
:1096A000C0B240002818418D1E482700FFB2C05D9F
|
||||
:1096B000FFF70EFB0028EBD1002000E00120F2BDF7
|
||||
:1096C00028F4001038B5164D2C89641C200080B297
|
||||
:1096C000CCF3001038B5164D2C89641C200080B2F4
|
||||
:1096D000F8F7A0FFF8F750FE200080B2FEF756FF23
|
||||
:1096E0002C8103206870F9F724FB286131BD38B55F
|
||||
:1096F0000A000B4BD978491C0C00057BE4B2AC4244
|
||||
:1097000003D30021DC88641CDC80C9B2FFF7D4FEDF
|
||||
:10971000002801D1FFF7D6FF31BD000030750000F1
|
||||
:10972000781A002828F40010F8B5C0B0002001F025
|
||||
:10972000781A0028CCF30010F8B5C0B0002001F082
|
||||
:1097300046FD20A9002000F098FA070069460120A4
|
||||
:1097400000F093FA04003800C0B2022801D10125CC
|
||||
:1097500000E000252000C0B2022801D1012600E06F
|
||||
@@ -2591,7 +2591,7 @@
|
||||
:10A1D0001500EDB22D015D196D6865601500EDB2D9
|
||||
:10A1E0002D015D19AD68A5601500EDB22D015B195B
|
||||
:10A1F0001B7B2373521C1300DBB2102B00D30022F5
|
||||
:10A200000A70FAF799FC012032BD000024F3001017
|
||||
:10A200000A70FAF799FC012032BD0000C8F2001074
|
||||
:10A2100000000440FF00FFFFFF0000FFF1B594B015
|
||||
:10A220000D0016005021002422006F463800FCF774
|
||||
:10A23000C3FF149880210901884203D24E48006868
|
||||
@@ -2639,7 +2639,7 @@
|
||||
:10A4D00059188C60027070BD2817002800B5C0B2F2
|
||||
:10A4E000002802D101200F49086000BDE01B0028B0
|
||||
:10A4F000DC1B0028D01B0028D41B0028005A620255
|
||||
:10A500006CEF0010A0EF0010D4EF0010800131407C
|
||||
:10A5000010EF001044EF001078EF00108001314090
|
||||
:10A51000C81B0028D81B0028B91C0028BA1C00281A
|
||||
:10A52000CC1B0028E41B002800B5BFF34F8F3D482B
|
||||
:10A53000AE490860BFF34F8F00BFFDE7AC490A6822
|
||||
@@ -2875,9 +2875,9 @@
|
||||
:10B39000D2B26946002002F027F900280CD0094DEE
|
||||
:10B3A000182209492800FCF7FFFDEC75F520074934
|
||||
:10B3B00008600020FCF758FE05B0F0BD00E100E099
|
||||
:10B3C0001CED00E0181B0028E8ED0010F01B002821
|
||||
:10B3C0001CED00E0181B0028ECED0010F01B00281D
|
||||
:10B3D0008BB100100800244000F4244000F5244004
|
||||
:10B3E000BB1C0028BC1C002814F3001000B500286A
|
||||
:10B3E000BB1C0028BC1C0028B8F2001000B50028C7
|
||||
:10B3F00001D0002901D1A04808E0A04A904206D11E
|
||||
:10B4000000200880802080014860002000BD9C4A08
|
||||
:10B41000904205D18020800102000A804860F4E754
|
||||
@@ -2930,7 +2930,7 @@
|
||||
:10B70000AD5DA4B2ADB2AC42EBD370BD000452400B
|
||||
:10B7100000065240000852400000544000025440CD
|
||||
:10B7200000045440000654400008544058080028C3
|
||||
:10B730000CF3001001085240301B0028F1B5A8B0EE
|
||||
:10B73000B0F2001001085240301B0028F1B5A8B04B
|
||||
:10B740000020009000202898FFF7BAFE0700002F85
|
||||
:10B7500029D0289E306D97490140002902D02898B1
|
||||
:10B76000FFF73EFF0125306DC00C284000281CD19A
|
||||
@@ -2970,7 +2970,7 @@
|
||||
:10B98000009A120A14400C43046078680028D3D04F
|
||||
:10B9900013AA012101207B689847CDE70648289922
|
||||
:10B9A000BC22895809094907490F415C891C0020BC
|
||||
:10B9B000B4E70000EEE0F73F0CF30010F1B594B0EF
|
||||
:10B9B000B4E70000EEE0F73FB0F20010F1B594B04C
|
||||
:10B9C000D34800681290D34800681190D2480768A5
|
||||
:10B9D000D2480668D24800681090D24800680F909C
|
||||
:10B9E000D14800680490D14800680E90D0480068A3
|
||||
@@ -3024,15 +3024,15 @@
|
||||
:10BCE000EB589B0814339B049B0C11409A001040A6
|
||||
:10BCF0000843C0216850802252021498000C0004AE
|
||||
:10BD00006946898A4018801806998B08002125E029
|
||||
:10BD10006CF3001070F3001074F3001078F300104F
|
||||
:10BD20007CF3001080F3001084F3001088F30010FF
|
||||
:10BD30008CF3001090F3001094F3001098F30010AF
|
||||
:10BD40009CF30010A0F30010A4F30010A8F300105F
|
||||
:10BD5000ACF3001000260660001D491C9942F9D37F
|
||||
:10BD100010F3001014F3001018F300101CF30010BF
|
||||
:10BD200020F3001024F3001028F300102CF300106F
|
||||
:10BD300030F3001034F3001038F300103CF300101F
|
||||
:10BD400040F3001044F3001048F300104CF30010CF
|
||||
:10BD500050F3001000260660001D491C9942F9D3DB
|
||||
:10BD600001990120084302210143CF480840217D69
|
||||
:10BD7000012901D1012100E00021CC4B0340480200
|
||||
:10BD80008021890008401843217D01290CD101211F
|
||||
:10BD90000BE000BFB0F30010B4F30010010062002C
|
||||
:10BD90000BE000BF54F3001058F3001001006200E4
|
||||
:10BDA000FFFF00FF0300FFFF0021C14B034008021B
|
||||
:10BDB000802149000840184380218843402188435E
|
||||
:10BDC0002021884310218843042188430190019851
|
||||
@@ -3046,7 +3046,7 @@
|
||||
:10BE4000E67F0E40F027B8433701F0263E40064318
|
||||
:10BE50002020205C01400F20864331432220205CBB
|
||||
:10BE6000012811D1012610E0FFFF80FFFCFF000038
|
||||
:10BE7000FFF8FFFFFFFFFF800CF30010FFFFFFC084
|
||||
:10BE7000FFF8FFFFFFFFFF80B0F20010FFFFFFC0E1
|
||||
:10BE8000FFFFC0FFFFFFFFBF00268F480840F105FE
|
||||
:10BE90008026360431400143E9602320215C1940AB
|
||||
:10BEA0000B9E8A4830400E02FE21C90131400143F9
|
||||
@@ -3126,7 +3126,7 @@
|
||||
:10C34000684600788540D0203D500020F2BD0000B6
|
||||
:10C35000301B002801006200FFFFFF1F030A0006D8
|
||||
:10C36000330A0000FFFFFFDFFFFFFFBFFFFF7FFF7C
|
||||
:10C37000FFFFF0FFFFFFDFFFFFFFEFFF0CF30010F9
|
||||
:10C37000FFFFF0FFFFFFDFFFFFFFEFFFB0F2001056
|
||||
:10C3800010B50200002A03D00800C0B2202801DB4B
|
||||
:10C39000002021E000200123CC241459CC401C4073
|
||||
:10C3A000002C09D0D4201058C8401840002801D1D2
|
||||
@@ -3229,7 +3229,7 @@
|
||||
:10C9B0002000F7F705FE4D492000F7F77BFC002823
|
||||
:10C9C00001D000200FE02000F7F707FE4849884219
|
||||
:10C9D00007D12000F7F7FDFD4649884201D101202B
|
||||
:10C9E00000E00020C0B210BD24F3001070B5424C2E
|
||||
:10C9E00000E00020C0B210BDC8F2001070B5424C8B
|
||||
:10C9F0000021216000F046F8002803D101202060CA
|
||||
:10CA000000203AE0374E002201213000FFF76FFE90
|
||||
:10CA1000354D37492800F7F7DEFD2800F7F7CAFD46
|
||||
@@ -3245,7 +3245,7 @@
|
||||
:10CAB00032BD10B50C48F7F783FD0A4C0022012166
|
||||
:10CAC000200000F07BF800220221200000F076F820
|
||||
:10CAD00010BD0000FF0000FF00FFFF00FFFCFFFF94
|
||||
:10CAE00038EF001080053140001E584018EB001050
|
||||
:10CAE000DCEE001080053140001E58400CEB0010B9
|
||||
:10CAF0001F4E0000204E0000C01B0028F8B5002586
|
||||
:10CB000000956846FBF706FA002801D0002045E0B2
|
||||
:10CB1000274C0098A04205D300982100F7F772FB3C
|
||||
@@ -3316,7 +3316,7 @@
|
||||
:10CF20001AE0534C2000F7F74BFB52492000F7F76B
|
||||
:10CF3000C1F9002801D000200EE02000F7F74DFBDA
|
||||
:10CF40004D49884206D12000F7F743FB002801D164
|
||||
:10CF5000012000E00020C0B210BD000024F300104A
|
||||
:10CF5000012000E00020C0B210BD0000C8F20010A7
|
||||
:10CF600070B5464C0021216000F046F8002803D13E
|
||||
:10CF70000120206000203AE03B4E002207213000D3
|
||||
:10CF8000FFF777FE3A4D3C492800F7F724FB2800CD
|
||||
@@ -3333,8 +3333,8 @@
|
||||
:10D03000FF0000FF80B50E48F7F7C2FA00F07AF85B
|
||||
:10D0400000200A49086001BD80B50948F7F7BDFA1C
|
||||
:10D05000C10B0800C007C00F02BD000000FFFF00A9
|
||||
:10D06000FFFCFFFF04EF001000083140B81B002850
|
||||
:10D0700080205840A4EA00101F4E0000BC1B00286E
|
||||
:10D06000FFFCFFFFA8EE001000083140B81B0028AD
|
||||
:10D070008020584098EA00101F4E0000BC1B00287A
|
||||
:10D08000F8B5002500956846FAF744FF002801D05E
|
||||
:10D09000002045E0354C0098A04205D300982100BF
|
||||
:10D0A000F7F7B0F8002901D0002039E000982100FE
|
||||
@@ -3388,11 +3388,11 @@
|
||||
:10D3A000300029001022F7F749FD00F017F8012896
|
||||
:10D3B00003D1032008E0022006E000F00FF8002867
|
||||
:10D3C00001D1002000E00420FEBD0000181B002851
|
||||
:10D3D00024E90010F01B00280010224010B5274C53
|
||||
:10D3D000A4E90010F01B00280010224010B5274CD3
|
||||
:10D3E00010212000FAF762FE2068000F0007A0213C
|
||||
:10D3F0000906884201D1002009E02068000F0007DB
|
||||
:10D40000F0210906884201D1012000E0022010BD70
|
||||
:10D41000ECF30010F0F30010000020400000224068
|
||||
:10D4100090F3001094F30010000020400000224020
|
||||
:10D42000FFFFFF0F38B50400FFF7D8FF0500280005
|
||||
:10D43000C0B2022801D142480DE0002C04D02000E7
|
||||
:10D4400027491022F7F7FAFCEDB2002D01D1002098
|
||||
@@ -3411,7 +3411,7 @@
|
||||
:10D5100001D1012600E002262800F040C00705D511
|
||||
:10D5200009480168002901D0006880472A0CA9B287
|
||||
:10D530002000FFF746FE70BDFFFFFF00801B0028A4
|
||||
:10D54000FFFFFF0F1CF30010E81B0028E5D40010BC
|
||||
:10D54000FFFFFF0FC0F20010E81B0028E5D4001019
|
||||
:10D550000000204050480068410B0800C007C00F81
|
||||
:10D5600070474D480068010B0800C007C00F7047A6
|
||||
:10D5700000B54A48012102680A43026002680A4075
|
||||
@@ -3445,7 +3445,7 @@
|
||||
:10D73000294820188021490288420FD201200EE09A
|
||||
:10D740008020000255496118814201D2012006E083
|
||||
:10D7500053496118814201D2012000E0002010BD30
|
||||
:10D76000FFFF00FF7CF2001010B50400FFF7F9FE88
|
||||
:10D76000FFFF00FF20F2001010B50400FFF7F9FEE4
|
||||
:10D77000002810D1F02000062018FE21C90388429D
|
||||
:10D7800001D2002026E0654820188021C902884285
|
||||
:10D790001FD200201EE0FE208003F0210906611840
|
||||
@@ -3504,7 +3504,7 @@
|
||||
:10DAE00015001E003800FFF7EFFF00280DD12900B8
|
||||
:10DAF0003800FFF7E5FF31003800FFF7E3FF2100B2
|
||||
:10DB00003800FFF7D5FF002000E00248F2BD00001A
|
||||
:10DB1000D8F3001001008A00F8B584B0F7F715FCBF
|
||||
:10DB10007CF3001001008A00F8B584B0F7F715FC1B
|
||||
:10DB2000BA49012708680322904338430860B8487F
|
||||
:10DB30000A6802400A60B7490A6803239A433A43D5
|
||||
:10DB40000A600A6802400A60B3490A6803239A43DC
|
||||
@@ -3589,8 +3589,8 @@
|
||||
:10E030004018FA218900F6F7E5F828602868C0033F
|
||||
:10E040001749086007B030BD041626400C19264059
|
||||
:10E050001C1926404016264044162640141226401D
|
||||
:10E06000E0F2001040122640080020400804204042
|
||||
:10E070000815264064F20010181B00286CEC0010F4
|
||||
:10E0600084F200104012264008002040080420409E
|
||||
:10E070000815264008F20010181B002860EC00105C
|
||||
:10E08000F01B0028941C0028981C00283F420F0019
|
||||
:10E0900040420F00A01C00289C1C0028E703000041
|
||||
:10E0A000A41C0028F3B595B0170000210D0008004E
|
||||
@@ -3672,7 +3672,7 @@
|
||||
:10E5600000210120FFF7ECFE0020FFF7DDFE012077
|
||||
:10E57000FFF7DAFE10BD000000E100E000E400E07B
|
||||
:10E580001CED00E000132040FFFFF7FF8013204048
|
||||
:10E59000A013204044F3001064EC001068EC00105D
|
||||
:10E59000A0132040E8F2001058EC00105CEC0010D2
|
||||
:10E5A00080000000001D00280000001008ED00E0C1
|
||||
:10E5B00000B5010009B2002905D40121C006C00E32
|
||||
:10E5C00081404A48016000BD00B5FEE780B548487B
|
||||
@@ -3694,23 +3694,23 @@
|
||||
:10E6C0000620FFF775FF01BD80B51848006818489F
|
||||
:10E6D0000068C10F002905D007498005800D800022
|
||||
:10E6E000085880470720FFF763FF01BD80E200E084
|
||||
:10E6F000B8F300100011204048090028BCF30010B6
|
||||
:10E7000004112040C0F3001008112040C4F3001091
|
||||
:10E710000C112040C8F3001010112040CCF3001061
|
||||
:10E7200014112040D0F3001018112040D4F3001031
|
||||
:10E730001C11204034F1001090F200108002314092
|
||||
:10E6F0005CF30010001120404809002860F300106E
|
||||
:10E700000411204064F300100811204068F3001049
|
||||
:10E710000C1120406CF300101011204070F3001019
|
||||
:10E720001411204074F300101811204078F30010E9
|
||||
:10E730001C112040D8F0001034F20010800231404B
|
||||
:10E740000400000008000000800658403A01000064
|
||||
:10E7500000093140020000000A0F0D07E00100002F
|
||||
:10E76000FC53000098210000F4010000E8030000C1
|
||||
:10E77000F4010000C0F10010A0F20010800231404E
|
||||
:10E77000F401000064F1001044F200108002314006
|
||||
:10E780000500000008000000000758403B010000A1
|
||||
:10E7900000053140010000000AF0D0707601000051
|
||||
:10E7A000E0150000D41700005E010000E80300003F
|
||||
:10E7B000F4010000DCF10010B0F200100004314060
|
||||
:10E7B000F401000080F1001054F200100004314018
|
||||
:10E7C00000000000080000008009584040010000DF
|
||||
:10E7D0000007314000000000090F0D0795030000FD
|
||||
:10E7E000901A000028230000F4010000E803000054
|
||||
:10E7F000F4010000F8F10010C0F200108000314078
|
||||
:10E7F000F40100009CF1001064F200108000314030
|
||||
:10E800000000000008000000000658403901000028
|
||||
:10E81000000631400500000009F0D07087020000BA
|
||||
:10E82000201C000098210000F4010000D007000027
|
||||
@@ -3729,169 +3729,169 @@
|
||||
:10E8F00075FCECE7F41B0028281200280648006885
|
||||
:10E9000070470020C04304490860044908600020A3
|
||||
:10E91000034908607047000000182640041826408C
|
||||
:10E9200008102640443A5C6875616E672E787565FC
|
||||
:10E930007765695C4769745C436F676E6974697673
|
||||
:10E94000655F4167656E745C2E636F6465785F74A4
|
||||
:10E950006D705C736561742D6669726D7761726547
|
||||
:10E960002D6275696C642D3031363932303434396A
|
||||
:10E97000363564343762306139303435613463613F
|
||||
:10E98000646131636231385C636F6D6D6F6E5C73AF
|
||||
:10E9900072635C647269766572735C6970635C63F0
|
||||
:10E9A000795F6970635F6472762E6800F1B4016804
|
||||
:10E9B0004118436858080A1800988068DB0701D599
|
||||
:10E9C0004B46C01891422DD00D78491C03240326D4
|
||||
:10E9D0002E4002D10E78F61C491C2B090F2B07D1B3
|
||||
:10E9E0000B780F33491C03E00F78491C0770401C5B
|
||||
:10E9F000761EF9D1002BE5D00E78491CAD082C40CD
|
||||
:10EA0000032C01D10C78491C2402341965424419A5
|
||||
:10EA10000025AE1E9E42D5D02678641C0670401C90
|
||||
:10EA20006D1CF6E700980C30F2BC704700053140D1
|
||||
:10EA30000600000000000000801890400200000066
|
||||
:10EA40000006314001000000000000004019904025
|
||||
:10EA50000500000000053140070000000000000034
|
||||
:10EA6000C018904003000000000531400500000080
|
||||
:10EA700000000000401890400100000000063140F6
|
||||
:10EA80000200000000000000801990400600000015
|
||||
:10EA9000000631400600000000000000801A90408F
|
||||
:10EAA0000A00000004000000000000000000000058
|
||||
:10EAB00000000000010003031F4E000000000000E2
|
||||
:10E9200008102640F1B401684118436858080A18D5
|
||||
:10E9300000988068DB0701D54B46C01891422DD066
|
||||
:10E940000D78491C032403262E4002D10E78F61CB4
|
||||
:10E95000491C2B090F2B07D10B780F33491C03E0FF
|
||||
:10E960000F78491C0770401C761EF9D1002BE5D0AA
|
||||
:10E970000E78491CAD082C40032C01D10C78491CA1
|
||||
:10E9800024023419654244190025AE1E9E42D5D09A
|
||||
:10E990002678641C0670401C6D1CF6E700980C304D
|
||||
:10E9A000F2BC7047443A5C50726F6A6563745C35C0
|
||||
:10E9B00031315C4E375765625C2E636F6465785FFA
|
||||
:10E9C000746D705C736561742D6669726D776172C8
|
||||
:10E9D000652D6275696C642D326530363863373762
|
||||
:10E9E00063306635346431386233393863383339EB
|
||||
:10E9F00063663830633463625C636F6D6D6F6E5C49
|
||||
:10EA00007372635C647269766572735C6970635C6F
|
||||
:10EA100063795F6970635F6472762E68000000003E
|
||||
:10EA20000005314006000000000000008018904002
|
||||
:10EA3000020000000006314001000000000000005C
|
||||
:10EA4000401990400500000000053140070000001B
|
||||
:10EA500000000000C0189040030000000005314095
|
||||
:10EA60000500000000000000401890400100000078
|
||||
:10EA700000063140020000000000000080199040B4
|
||||
:10EA80000600000000063140060000000000000003
|
||||
:10EA9000801A90400A0000000400000000000000FE
|
||||
:10EAA0000000000000000000010003031F4E0000F2
|
||||
:10EAB0000000000000000000000000000000000056
|
||||
:10EAC0000000000000000000000000000000000046
|
||||
:10EAD0000000000000000000000000000000000036
|
||||
:10EAE000000000000203000000000000030000001E
|
||||
:10EAF0000000000003000000000000000300000010
|
||||
:10EB000000000000030000000000000003000000FF
|
||||
:10EB100001000000010200000400000000000000ED
|
||||
:10EB20000000000000000000010003031F4E000071
|
||||
:10EB30000000000000000000204E00000000000067
|
||||
:10EB400000000000000000000000000000000000C5
|
||||
:10EB500000000000000000000203000000000000B0
|
||||
:10EB6000030000000000000003000000000000009F
|
||||
:10EB7000030000000000000003000000000000008F
|
||||
:10EB8000030000000100000001020000040000007A
|
||||
:10EB9000000000000000000000000000010003036E
|
||||
:10EBA00063000000000000000000000032000000D0
|
||||
:10EAD0000000000000000000020300000000000031
|
||||
:10EAE0000300000000000000030000000000000020
|
||||
:10EAF0000300000000000000030000000000000010
|
||||
:10EB000003000000010000000102000004000000FA
|
||||
:10EB100000000000000000000000000001000303EE
|
||||
:10EB20001F4E00000000000000000000204E00000A
|
||||
:10EB300000000000000000000000000000000000D5
|
||||
:10EB400000000000000000000000000002030000C0
|
||||
:10EB500000000000030000000000000003000000AF
|
||||
:10EB6000000000000300000000000000030000009F
|
||||
:10EB7000000000000300000001000000010200008E
|
||||
:10EB80000400000000000000000000000000000081
|
||||
:10EB9000010003036300000000000000000000000B
|
||||
:10EBA0003200000000000000000000000000000033
|
||||
:10EBB0000000000000000000000000000000000055
|
||||
:10EBC0000000000000000000000000000203000040
|
||||
:10EBD000000000000300000000000000030000002F
|
||||
:10EBE000000000000300000000000000030000001F
|
||||
:10EBF000000000000300000001000000010200000E
|
||||
:10EC000072B6104810490860BFF34F8F0120C0044E
|
||||
:10EC10000E490A6802430A600D490A6802430A6005
|
||||
:10EC20000C490A6802430A60002000210D4A03C211
|
||||
:10EC30006A45FCD1084FB847084FB847084FB84756
|
||||
:10EC4000FEE700000000001008ED00E00013204087
|
||||
:10EC500080132040A0132040B9E30010CDF0001035
|
||||
:10EC600031F2001000FF0128FFFF0128443A5C68E0
|
||||
:10EC700075616E672E7875657765695C4769745C48
|
||||
:10EC8000436F676E69746976655F4167656E745C32
|
||||
:10EC90006669726D776172655C7432675C747669FF
|
||||
:10ECA000696268386D5C7372635C73797374656DE7
|
||||
:10ECB0005C7265765F645C73797374656D5F74769E
|
||||
:10ECC00069696268386D5F636D30706C75732E634F
|
||||
:10ECD00000000000443A5C6875616E672E787565C7
|
||||
:10ECE0007765695C4769745C436F676E69746976C0
|
||||
:10ECF000655F4167656E745C6669726D77617265A8
|
||||
:10ED00005C7432675C747669696268386D5C7372D2
|
||||
:10ED1000635C647269766572735C737973636C6B40
|
||||
:10ED20005C63795F737973636C6B2E68000000001D
|
||||
:10ED3000443A5C6875616E672E7875657765695CC5
|
||||
:10ED40004769745C436F676E69746976655F416794
|
||||
:10ED5000656E745C6669726D776172655C7432674A
|
||||
:10ED60005C747669696268386D5C7372635C647246
|
||||
:10ED700069766572735C737973636C6B5C63795FDE
|
||||
:10ED8000737973636C6B2E6300000000443A5C6817
|
||||
:10ED900075616E672E7875657765695C4769745C27
|
||||
:10EDA000436F676E69746976655F4167656E745C11
|
||||
:10EDB0006669726D776172655C7432675C636F6DF2
|
||||
:10EDC0006D6F6E5C7372635C647269766572735C9E
|
||||
:10EDD0007379737469636B5C63795F737973746956
|
||||
:10EDE000636B2E6300000000443A5C6875616E67D7
|
||||
:10EDF0002E7875657765695C4769745C436F676EEB
|
||||
:10EE000069746976655F4167656E745C6669726D89
|
||||
:10EE1000776172655C7432675C636F6D6D6F6E5C99
|
||||
:10EE20007372635C6D775C666C6173685C63795F59
|
||||
:10EE30006D775F666C6173682E6300009F0F000042
|
||||
:10EE400000000000000000000000000000000000C2
|
||||
:10EE500000000300000000000000000000000000AF
|
||||
:10EE6000000300000000000003000000000000009C
|
||||
:10EE7000030000000000000003000000000000008C
|
||||
:10EE8000030000000100000000000000010000007D
|
||||
:10EE90000000000000000000100000001000000052
|
||||
:10EEA0001000000001000001000000000000000050
|
||||
:10EBC000020300000000000003000000000000003D
|
||||
:10EBD000030000000000000003000000000000002F
|
||||
:10EBE000030000000000000003000000010000001E
|
||||
:10EBF0000102000072B6104810490860BFF34F8F41
|
||||
:10EC00000120C0040E490A6802430A600D490A68DF
|
||||
:10EC100002430A600C490A6802430A60002000218E
|
||||
:10EC20000D4A03C26A45FCD1084FB847084FB847A0
|
||||
:10EC3000084FB847FEE700000000001008ED00E0B4
|
||||
:10EC40000013204080132040A0132040B9E300109F
|
||||
:10EC500071F00010D5F1001000FF0128FFFF01281E
|
||||
:10EC6000443A5C50726F6A6563745C3531315C4E56
|
||||
:10EC7000375765625C6669726D776172655C743284
|
||||
:10EC8000675C747669696268386D5C7372635C7323
|
||||
:10EC9000797374656D5C7265765F645C73797374A7
|
||||
:10ECA000656D5F747669696268386D5F636D307039
|
||||
:10ECB0006C75732E630000009F0F000000000000C1
|
||||
:10ECC0000000000000000000000000000000030041
|
||||
:10ECD0000000000000000000000000000003000031
|
||||
:10ECE000000000000300000000000000030000001E
|
||||
:10ECF000000000000300000000000000030000000E
|
||||
:10ED00000100000000000000443A5C50726F6A6528
|
||||
:10ED100063745C3531315C4E375765625C6669728D
|
||||
:10ED20006D776172655C7432675C7476696962687C
|
||||
:10ED3000386D5C7372635C647269766572735C7360
|
||||
:10ED40007973636C6B5C63795F737973636C6B2E3F
|
||||
:10ED500068000000443A5C50726F6A6563745C3509
|
||||
:10ED600031315C4E375765625C6669726D776172EE
|
||||
:10ED7000655C7432675C747669696268386D5C736F
|
||||
:10ED800072635C647269766572735C737973636CC9
|
||||
:10ED90006B5C63795F737973636C6B2E6300000047
|
||||
:10EDA000443A5C50726F6A6563745C3531315C4E15
|
||||
:10EDB000375765625C6669726D776172655C743243
|
||||
:10EDC000675C636F6D6D6F6E5C7372635C647269B8
|
||||
:10EDD000766572735C7379737469636B5C63795F76
|
||||
:10EDE0007379737469636B2E63000000443A5C505E
|
||||
:10EDF000726F6A6563745C3531315C4E375765629A
|
||||
:10EE00005C6669726D776172655C7432675C636FB2
|
||||
:10EE10006D6D6F6E5C7372635C6D775C666C617355
|
||||
:10EE2000685C63795F6D775F666C6173682E630001
|
||||
:10EE300001000000000000000000000010000000C1
|
||||
:10EE400010000000100000000100000100000000A0
|
||||
:10EE500000000000000000000000000000000000B2
|
||||
:10EE600000000000000000000000000070B401235A
|
||||
:10EE7000002413E00168001D194202D04D466918B4
|
||||
:10EE8000491E0C60091D121F042AFAD20D009607B4
|
||||
:10EE900001D50C80AD1C1A4000D02C700268001DFA
|
||||
:10EEA000002AE7D170BC7047000000000600000097
|
||||
:10EEB0000000000000000000000000000000000052
|
||||
:10EEC000000000000000000070B40123002413E0E3
|
||||
:10EED0000168001D194202D04D466918491E0C6098
|
||||
:10EEE000091D121F042AFAD20D00960701D50C80C5
|
||||
:10EEF000AD1C1A4000D02C700268001D002AE7D11A
|
||||
:10EF000070BC704700000000060000000000000018
|
||||
:10EF100000000000000000000000000000000000F1
|
||||
:10EEC0000000000000000000000000000000000042
|
||||
:10EED0000000000000000000000000000000000032
|
||||
:10EEE000060000000000000000000000000000001C
|
||||
:10EEF0000000000000000000000000000000000012
|
||||
:10EF00000000000000000000000000000000000001
|
||||
:10EF100000000000080000001500000000000000D4
|
||||
:10EF200000000000000000000000000000000000E1
|
||||
:10EF300000000000000000000000000006000000CB
|
||||
:10EF400000000000000000000000000000000000C1
|
||||
:10EF300000000000000000000000000000000000D1
|
||||
:10EF400000000000010000000E000000150000009D
|
||||
:10EF500000000000000000000000000000000000B1
|
||||
:10EF600000000000000000000000000000000000A1
|
||||
:10EF70000800000015000000000000000000000074
|
||||
:10EF7000000000000000000001000000060000008A
|
||||
:10EF80000000000000000000000000000000000081
|
||||
:10EF90000000000000000000000000000000000071
|
||||
:10EFA000010000000E00000015000000000000003D
|
||||
:10EFB0000000000000000000000000000000000051
|
||||
:10EFA0000000000000000000000000000000000061
|
||||
:10EFB000060000000000000000000000000000004B
|
||||
:10EFC0000000000000000000000000000000000041
|
||||
:10EFD000000000000100000006000000000000002A
|
||||
:10EFE0000000000000000000000000000000000021
|
||||
:10EFF0000000000000000000000000000000000011
|
||||
:10F0000000000000000000000000000006000000FA
|
||||
:10F0100000000000000000000000000000000000F0
|
||||
:10F0200000000000000000000000000000000000E0
|
||||
:10F0300000000000000000000000000002000000CE
|
||||
:10F0400000000000983A00000E01FA00CC01900187
|
||||
:10F05000020000000300000000000000983A0000D9
|
||||
:10F06000720182001C02CC010200000005000000B9
|
||||
:10F070000000000030750000F6001901BD02EE012D
|
||||
:10F0800002000000060000000000000030750000D3
|
||||
:10F0900087018C009501940102000000010000002E
|
||||
:10F0A00034F300103CF000100200000030F40010B7
|
||||
:10F0B00008003200020000003CF300106CF0001069
|
||||
:10F0C000020000002CF400100C00320010B50749BB
|
||||
:10F0D00079441831064C7C44163404E0081D0A6853
|
||||
:10F0E000891888470100A142F8D110BD080000002E
|
||||
:10F0F00024000000D5FDFFFFE409000008130028EC
|
||||
:10F1000000000000A9F8FFFF5E0300003A010000C4
|
||||
:10F1100000080028000003010000000001000000BA
|
||||
:10F12000000000000000000001000000FF0F0100CF
|
||||
:10F13000000000004D4F544F525F494E325F48422D
|
||||
:10F14000375F4842385F484F52495A4F4E54414CFE
|
||||
:10F150000000000004207146084202D0EFF309804D
|
||||
:10F1600001E0EFF3088000B50149884700BD0000C9
|
||||
:10F170006F80001000F00EF8002801D0FFF7A6FF06
|
||||
:10F1800000BF00BF002000BF00BFFFF75FFB00F023
|
||||
:10F1900003F800000020704780B500F001F801BDC1
|
||||
:10F1A0000746384600F002F8FBE7000080B500BFD4
|
||||
:10F1B00000BF024A11001820ABBEFBE72600020088
|
||||
:10F1C0004D4F544F525F494E335F4842355F48427E
|
||||
:10F1D000365F534541545F50414E00004D4F544FF0
|
||||
:10F1E000525F494E345F4842335F4842345F424188
|
||||
:10F1F000434B5245535400004D4F544F525F494EBC
|
||||
:10F20000315F4842315F4842325F4C454752455377
|
||||
:10F210005400000004207146084201D0EFF3098039
|
||||
:10F22000EFF3088000B50149884700BDF1F20010F6
|
||||
:10F230000548014603B4684680F3098800BF00BF53
|
||||
:10F2400000BF00BFFFF796FFA5EDF5FE9E029E0AE8
|
||||
:10F25000AA02AA0ACE03CE0B2A042A0C0003000B32
|
||||
:10F26000F002F00A00127A00000000000024F4000E
|
||||
:10F27000008000000080000000800000010002000B
|
||||
:10F28000040008001000200040008000000100027F
|
||||
:10F29000484F52495A4F4E54414C5F48414C4C00E4
|
||||
:10F2A000534541545F50414E5F48414C4C00000073
|
||||
:10F2B0004241434B524553545F48414C4C0000007F
|
||||
:10F2C0004C4547524553545F48414C4C00000000A8
|
||||
:10F2D000E02E0000401F0000E02E0000307500000E
|
||||
:10F2E0000003000100040103020200020003000504
|
||||
:10F2F0008169891E0978C9B2016070470000000069
|
||||
:10F3000000010101010101000001000002030405E8
|
||||
:10F3100006080C10000000000000000002000000C1
|
||||
:10F32000010000000403000113140015C7010300CD
|
||||
:10F33000010000004001BE00F401AE0187018C0015
|
||||
:10F340009501940100080028FFFF0128000000003B
|
||||
:10EFD0000000000000000000000000000000000031
|
||||
:10EFE0000200000000000000983A00000E01FA0044
|
||||
:10EFF000CC019001020000000300000000000000AE
|
||||
:10F00000983A0000720182001C02CC01020000004C
|
||||
:10F01000050000000000000030750000F600190136
|
||||
:10F02000BD02EE010200000006000000000000002A
|
||||
:10F030003075000087018C009501940102000000EA
|
||||
:10F0400001000000D8F20010E0EF00100200000004
|
||||
:10F05000D4F300100800320002000000E0F20010BB
|
||||
:10F0600010F0001002000000D0F300100C0032007D
|
||||
:10F0700010B5074979441831064C7C44163404E035
|
||||
:10F08000081D0A68891888470100A142F8D110BDFF
|
||||
:10F090000800000024000000D5FDFFFFE409000087
|
||||
:10F0A00008130028000000007DF8FFFF5E03000049
|
||||
:10F0B0003A010000000800280000030100000000E1
|
||||
:10F0C000010000000000000000000000010000003E
|
||||
:10F0D000FF0F0100000000004D4F544F525F494E9A
|
||||
:10F0E000325F4842375F4842385F484F52495A4F73
|
||||
:10F0F0004E54414C0000000004207146084202D0EA
|
||||
:10F10000EFF3098001E0EFF3088000B5014988477B
|
||||
:10F1100000BD00006F80001000F00EF8002801D044
|
||||
:10F12000FFF7A6FF00BF00BF002000BF00BFFFF732
|
||||
:10F130008DFB00F003F800000020704780B500F060
|
||||
:10F1400001F801BD0746384600F002F8FBE7000071
|
||||
:10F1500080B500BF00BF024A11001820ABBEFBE71C
|
||||
:10F16000260002004D4F544F525F494E335F4842D4
|
||||
:10F17000355F4842365F534541545F50414E000071
|
||||
:10F180004D4F544F525F494E345F4842335F4842BF
|
||||
:10F19000345F4241434B5245535400004D4F544F4E
|
||||
:10F1A000525F494E315F4842315F4842325F4C45C1
|
||||
:10F1B000475245535400000004207146084201D0D4
|
||||
:10F1C000EFF30980EFF3088000B50149884700BDDF
|
||||
:10F1D00095F200100548014603B4684680F309889B
|
||||
:10F1E00000BF00BF00BF00BFFFF796FFA5EDF5FE13
|
||||
:10F1F0009E029E0AAA02AA0ACE03CE0B2A042A0C59
|
||||
:10F200000003000BF002F00A00127A000000000078
|
||||
:10F210000024F40000800000008000000080000056
|
||||
:10F2200001000200040008001000200040008000DF
|
||||
:10F2300000010002484F52495A4F4E54414C5F481A
|
||||
:10F24000414C4C00534541545F50414E5F48414C46
|
||||
:10F250004C0000004241434B524553545F48414CDF
|
||||
:10F260004C0000004C4547524553545F48414C4CBC
|
||||
:10F2700000000000E02E0000401F0000E02E000013
|
||||
:10F2800030750000000300010004010302020002C7
|
||||
:10F29000000300058169891E0978C9B201607047C1
|
||||
:10F2A0000000000000010101010101000001000057
|
||||
:10F2B0000203040506080C10000000000000000016
|
||||
:10F2C00002000000010000000403000113140015F7
|
||||
:10F2D000C7010300010000004001BE00F401AE01BF
|
||||
:10F2E00087018C009501940100080028FFFF012888
|
||||
:10F2F000000000000000000000000000000000000E
|
||||
:10F3000000000000000000000000000000000000FD
|
||||
:10F3100000000000000000000000000000000000ED
|
||||
:10F3200000000000000000000000000000000000DD
|
||||
:10F3300000000000000000000000000000000000CD
|
||||
:10F3400000000000000000000000000000000000BD
|
||||
:10F3500000000000000000000000000000000000AD
|
||||
:10F36000000000000000000000000000000000009D
|
||||
:10F37000000000000000000000000000000000008D
|
||||
@@ -3899,27 +3899,27 @@
|
||||
:10F39000000000000000000000000000000000006D
|
||||
:10F3A000000000000000000000000000000000005D
|
||||
:10F3B000000000000000000000000000000000004D
|
||||
:10F3C000000000000000000000000000000000003D
|
||||
:10F3D000000000000000000000000000000000002D
|
||||
:10F3E000000000000000000000000000000000001D
|
||||
:10F3F000000000000000000000000000000000000D
|
||||
:10F4000000000000000000000000000000000000FC
|
||||
:10F4100000000000000000000000000000000000EC
|
||||
:10F4200000000000000000000001020332325A32E6
|
||||
:10F430005A5A5A32000102035A5A5A32FEE7000061
|
||||
:10F44000FEE70000FEE70000FEE70000FEE7000028
|
||||
:10F45000FEE70000FEE70000FEE70000FEE7000018
|
||||
:10F46000FEE70000FEE740045500020001000150E5
|
||||
:10F470000325A40010000132DD0CA00409000401E2
|
||||
:10F4800001000112060E834CF2286004FFFFFF1FEB
|
||||
:10F49000020225920807F0010352400001F2060221
|
||||
:10F4A00018F2060418F2060618F2060818F3060009
|
||||
:10F4B0005478F10618F2060418F2060618F2050848
|
||||
:10F4C00018F002FFC9E5001004F1FF04F1FF04F198
|
||||
:10F4D000FF04F1FF04F1FF04F1FF04F1FF04F14721
|
||||
:10F4E000046C0248090028060AF321060001F123F2
|
||||
:10F4F00034F2520868000A01010102030203010FFD
|
||||
:10F500000F010100000000000000000000000000EA
|
||||
:10F3C0000000000000000000000000000001020337
|
||||
:10F3D00032325A325A5A5A32000102035A5A5A32B7
|
||||
:10F3E000FEE70000FEE70000FEE70000FEE7000089
|
||||
:10F3F000FEE70000FEE70000FEE70000FEE7000079
|
||||
:10F40000FEE70000FEE70000FEE7400455000200B2
|
||||
:10F41000010001500325A40010000132DD0CA004FE
|
||||
:10F420000900040101000112060E83F0F1286004B6
|
||||
:10F43000FFFFFF1F020225920807F0010352400060
|
||||
:10F4400001F2060218F2060418F2060618F206087F
|
||||
:10F4500018F306005478F10618F2060418F20606AE
|
||||
:10F4600018F2050818F002FFC9E5001004F1FF04C6
|
||||
:10F47000F1FF04F1FF04F1FF04F1FF04F1FF04F1D7
|
||||
:10F48000FF04F147046C0248090028060AF321062C
|
||||
:10F490000001F12334F2520868000A01010102035D
|
||||
:10F4A0000203010F0F010100000000000000000036
|
||||
:10F4B000000000000000000000000000000000004C
|
||||
:10F4C000000000000000000000000000000000003C
|
||||
:10F4D000000000000000000000000000000000002C
|
||||
:10F4E000000000000000000000000000000000001C
|
||||
:10F4F000000000000000000000000000000000000C
|
||||
:10F5000000000000000000000000000000000000FB
|
||||
:10F5100000000000000000000000000000000000EB
|
||||
:10F5200000000000000000000000000000000000DB
|
||||
:10F5300000000000000000000000000000000000CB
|
||||
@@ -3937,11 +3937,6 @@
|
||||
:10F5F000000000000000000000000000000000000B
|
||||
:10F6000000000000000000000000000000000000FA
|
||||
:10F6100000000000000000000000000000000000EA
|
||||
:10F6200000000000000000000000000000000000DA
|
||||
:10F6300000000000000000000000000000000000CA
|
||||
:10F6400000000000000000000000000000000000BA
|
||||
:10F6500000000000000000000000000000000000AA
|
||||
:10F66000000000000000000000000000000000009A
|
||||
:0DF67000000000000000000000000000008D
|
||||
:040000051000F231C4
|
||||
:01F6200000E9
|
||||
:040000051000F1D521
|
||||
:00000001FF
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user