Загрузка данных
freq = HAL_ClockGetIpFreq(hal_clock_m7);
PRINTF("\r\n#################### Power Mode Switch Task ####################\n\r\n");
PRINTF(" Build Time: %s--%s \r\n", __DATE__, __TIME__);
PRINTF(" Core Clock: %dHz \r\n", freq);
PRINTF("\r\nSelect the desired operation \n\r\n");
PRINTF("Press %c to enter: Normal RUN mode\r\n", kAPP_PowerModeRun);
PRINTF("Press %c to enter: WAIT mode\r\n", kAPP_PowerModeWait);
PRINTF("Press %c to enter: STOP mode\r\n", kAPP_PowerModeStop);
PRINTF("Press %c to enter: SUSPEND mode\r\n", kAPP_PowerModeSuspend);
PRINTF("Press P to suspend A55 core\r\n");
PRINTF("Press W to wakeup A55 core\r\n");
PRINTF("Press M to memtest DDR\r\n");
PRINTF("Press D to DIRECTLY suspend A55 via SCMI to M33\r\n"); /* <- Новая строка в меню */
PRINTF("\r\nWaiting for power mode select..\r\n\r\n");
/* Wait for user response */
do
{
ch = GETCHAR();
} while ((ch == '\r') || (ch == '\n'));
if ((ch >= 'a') && (ch <= 'z'))
{
ch -= 'a' - 'A';
}
int modeIndex = ch - 'A';
/* Добавляем 'D' в список исключений для валидации ввода */
if ((ch != 'P') && (ch != 'W') && (ch != 'M') && (ch != 'D') && ((modeIndex < 0) || (modeIndex >= LPM_PowerModeCount)))
{
PRINTF("Invalid power mode input: %c\r\n", ch);
continue;
}
targetPowerMode = (lpm_power_mode_t)modeIndex;
if (targetPowerMode < LPM_PowerModeCount)
{
/* ... (Ваш существующий код обработки стандартных режимов питания) ... */
}
else if ('P' == ch)
{
/* ... (Ваш существующий код для обычного перевода А55 в suspend) ... */
}
else if ('W' == ch)
{
/* ... (Ваш существующий код для обычного wakeup А55) ... */
}
else if ('M' == ch)
{
PRINTF("%s(%d)\r\n",__FUNCTION__,__LINE__);
run_intense_memtest_loop(DDR_TEST_START_ADDR, DDR_TEST_SIZE_WORDS);
PRINTF("%s(%d)\r\n",__FUNCTION__,__LINE__);
}
/* >>> НАЧАЛО НОВОЙ КОМАНДЫ 'D' <<< */
else if ('D' == ch)
{
PRINTF("[DIRECT SCMI] Отправка команды принудительного отключения LMM A55 напрямую в М33...\r\n");
/*
Используем прямую SCMI команду для перевода домена приложений (AP_DOMAIN_LD)
в состояние выключения/приостановки через LMM протокол.
В зависимости от реализации SDK, для отправки в M33 используется дескриптор,
инициализированный на работу с Mailbox/Message Unit ядра System Manager.
Обычно это канал SCMI_A2P (так как M7 выступает в роли агента к платформе).
*/
status = SCMI_LmmSuspend(SCMI_A2P, AP_DOMAIN_LD);
if (status == SCMI_ERR_SUCCESS)
{
PRINTF("[SUCCESS] SCMI команда принята ядром M33. Домен A55 отключается.\r\n");
}
else
{
PRINTF("[ERROR] Прямой вызов SCMI_LmmSuspend завершился ошибкой: %d\r\n", status);
/* Альтернативный низкоуровневый вариант, если SCMI_LmmSuspend перегружен логикой SDK:
Отправка сырого сообщения через SCMI системный вызов (System Power Control) */
/*
scmi_system_power_state_set_t sysPower;
sysPower.flags = SCMI_SYS_POWER_FLAGS_GRACEFUL;
sysPower.systemState = SCMI_SYS_POWER_STATE_SUSPEND; // Или аналогичное состояние для AP
status = SCMI_SystemPowerStateSet(SCMI_A2P, &sysPower);
*/
}
}
/* >>> КОНЕЦ НОВОЙ КОМАНДЫ <<< */
else
{
PRINTF("Invalid command %c[0x%x]\r\n", ch, ch);
}
/* update Mode state */
s_curMode = LPM_PowerModeRun;
PRINTF("\r\nNext loop\r\n");