#include // // Created by xemon on 19.09.22. // #include "MainModesArbiter_Private.h" #include "Flash_MT29F2G01ABAGDWB.h" #include "http_server.h" #include "at32_emac.h" #include "netconf.h" //#include "BootJump.h" #include "AtCmdCommonProtected.h" #include #include "at32_sdio.h" #include "ff.h" #include "tcp_server.h" #include "AtGsmSim800f.h" #include "i2c_smbus.h" #include "delay_sec.h" #include "stdlib.h" #include "MainModesArbiter.h" #include "stdio.h" #include "stdarg.h" #include "at32f435_437_emac.h" #define LOG_SIGN "Главн." #define LOGGER &env->slog.logger void TaskTcpLoop_Init( tTaskTcpLoop *env ) { //Инициализируем поток InitThreadAtrStatic(&env->thread.attr, "TaskTcpLoop_Thread", env->thread.controlBlock, env->thread.stack, osPriorityNormal); env->thread.id = 0; } void sys_check_timeouts(void); #include "lwip/stats.h" extern tMma MAIN_ENV; //#define LWIP_DEBUG 1 static _Noreturn void TaskTcpLoop_Thread(tTaskTcpLoop *env) { for (;;) { #ifdef LWIP_DEBUG stats_display(); #endif SystemDelayMs(5000); } } char bufLwIpWebStats[4096]; uint32_t bufLwIpWebStepStats = 0; // uprintf // lwip_win32_platform_diag int16_t uprintf(const char *fmt, ...) { char bufLwIpStats[1024]; int16_t bufLwIpStatsLen = 0; bufLwIpStatsLen = -1; va_list ap; #ifdef LWIP_DEBUG char str[9]; // Вернет ошибку, если формат является указателем NULL: if (!fmt) { return -1; } // Вернет ошибку, если строка превышает размер буфера, с учетом // необходимых дополнительных 2 символов: CR и нулевой терминатор ASCIIZ: if (sizeof(bufLwIpStats) - 2 < strlen(fmt)) { return -1; } va_start (ap, fmt); bufLwIpStatsLen = vsprintf(bufLwIpStats, fmt, ap); bufLwIpStats[bufLwIpStatsLen + 1] = 0; va_end (ap); for (int i = 0; i < bufLwIpStatsLen; ++i) { bufLwIpWebStats[bufLwIpWebStepStats] = bufLwIpStats[i]; ++bufLwIpWebStepStats; if (bufLwIpWebStepStats >= sizeof(bufLwIpWebStats)) bufLwIpWebStepStats = 0; } // SerialPortTransmit(&MAIN_ENV.serialPorts->ComIntHalfDuplexIo, (uint8_t *) bufLwIpStats, bufLwIpStatsLen, 100); // buf[0] = '\0'; // strcat(buf, "error summary: "); // utoa((EMAC_DMARXDESC_ES), str, 10); #endif return bufLwIpStatsLen; } void TaskTcpLoop_StartThread(tTaskTcpLoop *env) { if (!env->thread.id) { env->thread.id = osThreadNew((osThreadFunc_t) (TaskTcpLoop_Thread), (void *) (env), &env->thread.attr); } else { osThreadResume(env->thread.id); } } void Mma_Init( tMma *env, tGpios *gpios, tAdcs *adcs, tSerialPorts *serialPorts, tSpiPorts *spiPorts, tRtcs *rtcs, tStorageOnFlash *flash, tFirmwareLoader *firmwareMainLoader, tFirmwareLoader *firmwareBootLoader ) { env->gpios = gpios; env->adcs = adcs; env->serialPorts = serialPorts; // env->i2cPorts = i2cPorts; env->spiPorts = spiPorts; env->rtcs = rtcs; env->flash = flash; env->firmwareMainLoader = firmwareMainLoader; env->firmwareBootLoader = firmwareBootLoader; InitThreadAtrStatic(&env->thread.attr, "Mma", env->thread.controlBlock, env->thread.stack, osPriorityNormal); env->thread.id = 0; } /* void Mma_Shutdown(tMma *env) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Завершение работы") VarsTabDumpObserver_Flush(&env->storage.dumpObserver); LoggerInfoStatic(LOGGER, LOG_SIGN, "Отключение питания через 1с") SystemDelayMs(1000); Pwm_Blackout(&env->power); LoggerInfoStatic(LOGGER, LOG_SIGN, "Питание осталось, обратите внимание!!") LoggerInfoStatic(LOGGER, LOG_SIGN, "Возможно произошло повторное включение пользователем") SystemDelayMs(5000); BootJumpToAddress(0x8000000); LoggerErrorStatic(LOGGER, LOG_SIGN, "Этой строчки не должно быть! Критическая ошибка!") } void Mma_CheckShutdown(tMma *env) { if (Pwm_IsShutdownRequired(&env->power) && !(EraGlonassUveos_IsStandby(&env->uveos))) { Mma_Shutdown(env); } } void Mma_GaragMode(tMma *env) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Переход в режим Гараж") Mma_SetMode(env, DEVICE_MODE_UVEOS_GARAG_MODE); GpioPinEnable(&env->power.pins->main.garage); EraGlonassUveos_GarageStarted(&env->uveos); tUserInputButtonEvent buttonEvent; while (1) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Режим Гараж") GsmWithGnss_UpdateGnssData(&env->gsmWithGnss); if (EraGlonassUveos_IsBreakGarage(&env->uveos)) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматический выход из режима Гараж") GpioPinDisable(&env->power.pins->main.garage); GpioPinDisable(&env->power.pins->main.muteP); break; } if (UserButtons_GetNext(&env->userInput.buttonsInterface, &buttonEvent, 10)) { if (UserInputButtonEventIsBetween(buttonEvent, UI_BUTTON_ADDITIONAL, RAISE, 3000, 0xFFFF)) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Пользовательский выход из режима Гараж") GpioPinDisable(&env->power.pins->main.garage); GpioPinDisable(&env->power.pins->main.muteP); break; } } SystemDelayMs(5000); } } void Mma_RunTestingMode(tMma *env) { LoggerTraceStatic(LOGGER, LOG_SIGN, "Включаем регистрацию в сети"); GsmWithGnss_SetNetworkRegistration(&env->gsmWithGnss, true); //задаем режим и обновляем индикторы Mma_SetMode(env, DEVICE_MODE_TESTING); //выключаем индикацию UserIndication_StopThread(&env->indication); //запускаем режим тестирования с пользователем DeviceTesting_MainTestingMode(&env->testing); //включаем индикацию UserIndication_StartThread(&env->indication); } static void Mma_NetworkAndAudioEnable(tMma *env) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Включаем регистрацию в сети"); GsmWithGnss_SetNetworkRegistration(&env->gsmWithGnss, true); LoggerInfoStatic(LOGGER, LOG_SIGN, "Ждем сеть..."); if (GsmWithGnss_WaitNetworkRegistration(&env->gsmWithGnss)) { LoggerInfoStatic(LOGGER, LOG_SIGN, "зерегестрировались"); } else { LoggerErrorStatic(LOGGER, LOG_SIGN, "нет сети"); }; LoggerInfoStatic(LOGGER, LOG_SIGN, "Включаем звук"); } */ extern osMessageQueueId_t EthDataQueue; void EMAC_IRQHandler(void) { while (emac_received_packet_size_get() != 0) { lwip_pkt_set_queue_handle(EthDataQueue); } emac_dma_flag_clear(EMAC_DMA_RI_FLAG); emac_dma_flag_clear(EMAC_DMA_NIS_FLAG); /* while (emac_received_packet_size_get() != 0) { lwip_pkt_handle(); } emac_dma_flag_clear(EMAC_DMA_RI_FLAG); emac_dma_flag_clear(EMAC_DMA_NIS_FLAG); */ } #include "JSONSettings.h" //char buffer[2048]; extern tMma MAIN_ENV; /* void exint_line6_config(void) { exint_init_type exint_init_struct; crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE); scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOE, SCFG_PINS_SOURCE6); exint_default_para_init(&exint_init_struct); exint_init_struct.line_enable = TRUE; exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT; exint_init_struct.line_select = EXINT_LINE_6; exint_init_struct.line_polarity = EXINT_TRIGGER_BOTH_EDGE; exint_init(&exint_init_struct); NVIC_EnableIRQ(EXINT9_5_IRQn); NVIC_SetPriority(EXINT9_5_IRQn, 0x54); } void EXINT9_5_IRQHandler(void) { bool pwr = GpioPinGet(&MAIN_ENV.gpios->Power.gonec_pwr_amp); if (pwr) { GpioPinSet(&MAIN_ENV.gpios->Power.tx_pwr_en, true); delay_ms(100); sendI2c(); } else { GpioPinSet(&MAIN_ENV.gpios->Power.tx_pwr_en, false); } if (exint_flag_get(EXINT_LINE_6) != RESET) { exint_flag_clear(EXINT_LINE_6); } } void exint_line2_config(void) { exint_init_type exint_init_struct; crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE); scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOE, SCFG_PINS_SOURCE2); exint_default_para_init(&exint_init_struct); exint_init_struct.line_enable = TRUE; exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT; exint_init_struct.line_select = EXINT_LINE_2; exint_init_struct.line_polarity = EXINT_TRIGGER_BOTH_EDGE; exint_init(&exint_init_struct); NVIC_EnableIRQ(EXINT2_IRQn); NVIC_SetPriority(EXINT2_IRQn, 0x54); } bool isPrmModem = false; void EXINT2_IRQHandler(void) { bool isPrm = GpioPinGet(&MAIN_ENV.gpios->Power.gonec_is_prm); if (isPrm) { isPrmModem = true; } if (exint_flag_get(EXINT_LINE_2) != RESET) { exint_flag_clear(EXINT_LINE_2); } } */ /* void exint_line_2_6_config(void) { exint_init_type exint_init_struct; crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE); scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOE, SCFG_PINS_SOURCE2); scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOE, SCFG_PINS_SOURCE6); exint_default_para_init(&exint_init_struct); exint_init_struct.line_enable = TRUE; exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT; exint_init_struct.line_select = EXINT_LINE_2 | EXINT_LINE_6; exint_init_struct.line_polarity = EXINT_TRIGGER_BOTH_EDGE; exint_init(&exint_init_struct); NVIC_EnableIRQ(EXINT2_IRQn); NVIC_SetPriority(EXINT2_IRQn, 0x54); NVIC_EnableIRQ(EXINT9_5_IRQn); NVIC_SetPriority(EXINT9_5_IRQn, 0x54); } void EXINT9_5_IRQHandler(void) { bool pwr = GpioPinGet(&MAIN_ENV.gpios->Power.gonec_pwr_amp); if (pwr) { GpioPinSet(&MAIN_ENV.gpios->Power.tx_pwr_en, true); delay_ms(100); sendI2c(); } else { GpioPinSet(&MAIN_ENV.gpios->Power.tx_pwr_en, false); } if (exint_flag_get(EXINT_LINE_6) != RESET) { exint_flag_clear(EXINT_LINE_6); } } bool isPrmModem = false; void EXINT2_IRQHandler(void) { bool isPrm = GpioPinGet(&MAIN_ENV.gpios->Power.gonec_is_prm); if (isPrm) { isPrmModem = true; } if (exint_flag_get(EXINT_LINE_2) != RESET) { exint_flag_clear(EXINT_LINE_2); } } */ //uint8_t bufAnswer[40000]; //#define t1asm(tns) asm(".rept " #tns " ; nop ; .endr"); static _Noreturn void Mma_Thread(tMma *env) { // t1asm(8 * 40); // asm(".rept 1000 ; nop ; .endr"); // if (!DeviceStorage_Init(&env->storage, &env->flash->interface)) { // Mma_FatalErrorOnInit(env, DEVICE_MODE_ERROR_FLASH); // } // env->storageIni.logger = &env->slog.logger; // env->storage.dumpObserver.logger = &env->slog.logger; // Сохранение настроек во временные // NvmToRuntimeSettings(); // Перенастройка порта ComInt485 vSerialPort_ReInitUSART2(env->storageIni.nvm.Settings_RS485_Bluetooth.rs485baudrate_v); env->accessHTTP = osMutexNew(NULL); env->accessMODEM = osMutexNew(NULL); env->accessLOG = osMutexNew(NULL); env->accessLOG2 = osMutexNew(NULL); env->accessTracert = osMutexNew(NULL); env->accessMODEM_GSM = osMutexNew(NULL); // Запуск устройства Mma_InitStage(env); // error_status status = emac_system_init_eth(); // while (status == ERROR); // tcpip_stack_init(); httpd_init(&env->external, &env->rtcs->rtcI0, &env->taskAdc, &env->storageIni, &env->fs, env->spiPorts, env->firmwareMainLoader, env->firmwareBootLoader, &env->modemMain, env->accessHTTP, env->accessMODEM, env->accessLOG, env->accessLOG2, env->gpios, &env->flog, &env->modemMainLog); TaskTcpLoop_Init(&env->taskTcpLoop); TaskTcpLoop_StartThread(&env->taskTcpLoop); // exint_line_2_6_config(); // exint_line2_config(); // tcp_server_init(); // spi_flash_unblock(&env->spiPorts->flashSPI1IO, 1000); // spi_flash_unblock(&env->spiPorts->flashSPI2IO, 1000); // eDeviceModes indicationState; // tUserInputButtonEvent buttonEvent; // tUveosEmergencyEvent emergencyEvent; // while (!EraGlonassUveos_IsEraAllowed(&env->uveos)) { // Mma_SetMode(env, DEVICE_MODE_UVEOS_PASSIVE); // LoggerInfoStatic(LOGGER, LOG_SIGN, "Пассивный режим, сконфигурируйте устройство!") // SystemDelayMs(3000); // } // Gsm_WaitStartup(&env->gsm); // Mma_Network_Require(env); // exint_line0_config(); //GpioPinSet(&env->gpios->comIntDir.transmit, true); /* FIL file; UINT bytes_read; int step = 0; while (1) { FRESULT fr = f_open_i(httpSettings.fs, &file, "1:/LOG2/31-05-23.LOG", FA_READ); if (fr) { asm("nop"); } if (step == 1) fr = f_lseek_i(httpSettings.fs, &file, 40000); if (step == 2) fr = f_lseek_i(httpSettings.fs, &file, 80000); ++step; if (step == 3) step = 0; uint32_t t1 = SystemGetMs(); fr = f_read_i(httpSettings.fs, &file, bufAnswer, 40000, &bytes_read); uint32_t t2 = SystemGetMs(); uint32_t t3 = t2 - t1; if (t3 > 10) { asm("nop"); } f_close_i(httpSettings.fs, &file); } */ volatile uint32_t stepPack = 0; volatile uint32_t stepDiscardPack = 0; for (;;) { /* struct pbuf *p = NULL; osStatus_t status = osMessageQueueGet(EthDataQueue, &p, NULL, 100); lwip_periodic_handle(SystemGetMs()); sys_check_timeouts(); if (status == osOK) { //uint32_t t1 = SystemGetMs(); lwip_pkt_get_queue_handle(p); //uint32_t t2 = SystemGetMs(); //uint32_t t3 = t2 - t1; ++stepPack; } else { ++stepDiscardPack; } */ lwip_periodic_handle(SystemGetMs()); sys_check_timeouts(); while (emac_received_packet_size_get() != 0) { lwip_pkt_handle(); } SystemDelayMs(1); /* LoggerTraceStatic(LOGGER, LOG_SIGN, "Начало итерации главного цикла") LoggerTraceStatic(LOGGER, LOG_SIGN, "Проверяем нужна ли сеть...") if (EraGlonassUveos_IsRequireNetwork(&env->uveos)) { LoggerTraceStatic(LOGGER, LOG_SIGN, "Нужна, подключаемся") GsmWithGnss_SetNetworkRegistration(&env->gsmWithGnss, true); } else { LoggerTraceStatic(LOGGER, LOG_SIGN, "Ненужна, отключаемся") GsmWithGnss_SetNetworkRegistration(&env->gsmWithGnss, false); } LoggerTraceStatic(LOGGER, LOG_SIGN, "Обновление ГНСС") if (env->storage.runtime.enableGnssUpdate) { GsmWithGnss_UpdateGnssData(&env->gsmWithGnss); indicationState = GsmWithGnss_IsGnssReady(&env->gsmWithGnss) ? DEVICE_MODE_UVEOS_ERA_GNSS_READY : DEVICE_MODE_UVEOS_ERA_WAIT_GNSS; } else { indicationState = DEVICE_MODE_UVEOS_ERA_WAIT_GNSS; } LoggerTraceStatic(LOGGER, LOG_SIGN, "Выполняем постоянный тест") if (DeviceTesting_Always(&env->testing)) { indicationState = DEVICE_MODE_FAILURE; }; LoggerTraceStatic(LOGGER, LOG_SIGN, "Выполняем периодическое тестирование") DeviceTesting_Periodical(&env->testing); LoggerTraceStatic(LOGGER, LOG_SIGN, "Обновляем индикацию") Mma_SetMode(env, indicationState); LoggerTraceStatic(LOGGER, LOG_SIGN, "Проверяем экстренное событие") if (UveosEmergencyEvent_GetNext(&env->crashDetect.emergencyEvents, &emergencyEvent, 0)) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Экстренное событие получено"); GpioPinEnable(&env->power.pins->main.ecall); Mma_NetworkAndAudioEnable(env); GpioPinDisable(&env->power.pins->main.ecall); GpioPinDisable(&env->power.pins->main.muteP); EraGlonassUveos_ProcessingEmergencyEvent(&env->uveos, &emergencyEvent); } LoggerTraceStatic(LOGGER, LOG_SIGN, "Проверяем нажатия кнопок") if (UserButtons_GetNext(&env->userInput.buttonsInterface, &buttonEvent, 10)) { if (UserInputButtonEventIsBetween( buttonEvent, UI_BUTTON_EMERGENCY, RAISE, env->storage.nvm.gost.SOS_BUTTON_TIME, 0xFFFF )) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Нажата кнопка экстренного вызова"); Mma_NetworkAndAudioEnable(env); GpioPinEnable(&env->power.pins->main.ecall); EraGlonassUveos_ManualEmergencyCall(&env->uveos); GpioPinDisable(&env->power.pins->main.ecall); GpioPinDisable(&env->power.pins->main.muteP); } if (UserInputButtonEventIsBetween(buttonEvent, UI_BUTTON_ADDITIONAL, RAISE, 3000, 10000)) { Mma_NetworkAndAudioEnable(env); Mma_RunTestingMode(env); } else if (UserInputButtonEventIsBetween(buttonEvent, UI_BUTTON_ADDITIONAL, RAISE, 10000, 30000)) { Mma_GaragMode(env); } } Mma_CheckShutdown(env); SystemDelayMs(10); */ } } void Mma_StartThread(tMma *env) { if (!env->thread.id) { env->thread.id = osThreadNew((osThreadFunc_t) (Mma_Thread), (void *) (env), &env->thread.attr); } else { osThreadResume(env->thread.id); } }