aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/PowerOffViewVM.cs
blob: e3ab7d111519c28141565de07afa8bd11a0ad9c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Core.Commands;
using Tango.Integration.Operation;
using Tango.PMR.Power;
using Tango.PPC.Common;
using Tango.PPC.UI.AppBarItems;
using Tango.PPC.UI.Views;

namespace Tango.PPC.UI.ViewModels
{
    public class PowerOffViewVM : PPCViewModel
    {
        private PowerDownHandler _handler;
        private PowerOffAppBarItem _appBarItem;
        private int _abortTries;

        private StartPowerDownResponse _status;
        public StartPowerDownResponse Status
        {
            get { return _status; }
            set { _status = value; RaisePropertyChangedAuto(); }
        }

        public RelayCommand AbortCommand { get; set; }

        public PowerOffViewVM()
        {
            _appBarItem = new PowerOffAppBarItem();
            _appBarItem.Pressed += (x, e) =>
            {
                NavigationManager.NavigateTo<InternalModule>(nameof(PowerOffView));
            };
            AbortCommand = new RelayCommand(AbortPowerOff);
        }

        public override void OnApplicationStarted()
        {

        }

        public override void OnApplicationReady()
        {
            base.OnApplicationReady();
            MachineProvider.MachineOperator.PowerDownStarted += MachineOperator_PowerDownStarted;
        }

        private void MachineOperator_PowerDownStarted(object sender, PowerDownStartedEventArgs e)
        {
            _abortTries = 0;
            _handler = e.Handler;

            _handler.StatusChanged += OnStatusChanged;
            _handler.Failed += OnFailed;
            _handler.Completed += OnCompleted;

            InvokeUI(async () =>
            {
                await NavigationManager.NavigateTo<InternalModule>(nameof(PowerOffView));
                NotificationProvider.PushAppBarItem(_appBarItem);
            });
        }

        private void OnStatusChanged(object sender, PowerDownStatusChangedEventArgs e)
        {
            Status = e.Status;
            _appBarItem.Status = Status;
        }

        private void OnCompleted(object sender, EventArgs e)
        {
            InvokeUI(async () =>
            {
                if (IsVisible)
                {
                    await NavigationManager.NavigateBack();
                }

                NotificationProvider.PopAppBarItem(_appBarItem);
            });
        }

        private void OnFailed(object sender, Exception ex)
        {
            InvokeUI(async () =>
            {
                await NotificationProvider.ShowError($"An error occurred while powering off the machine.\n{ex.FlattenMessage()}");

                if (IsVisible)
                {
                    await NavigationManager.NavigateBack();
                }

                NotificationProvider.PopAppBarItem(_appBarItem);
            });
        }

        private async void AbortPowerOff()
        {
            try
            {
                NotificationProvider.SetGlobalBusyMessage("Aborting machine power off...");
                await _handler.Abort();
                await NavigationManager.NavigateBack();
                NotificationProvider.PopAppBarItem(_appBarItem);
            }
            catch (Exception ex)
            {
                _abortTries++;
                LogManager.Log(ex, "Power down abort error.");
                NotificationProvider.ReleaseGlobalBusyMessage();
                await NotificationProvider.ShowError($"An error occurred while trying to abort the power off sequence.\n{ex.FlattenMessage()}");

                if (_abortTries > 2)
                {
                    if (IsVisible)
                    {
                        await NavigationManager.NavigateBack();
                    }

                    NotificationProvider.PopAppBarItem(_appBarItem);
                }
            }
            finally
            {
                NotificationProvider.ReleaseGlobalBusyMessage();
            }
        }
    }
}
n> uint32_t Dancer_Data[NUM_OF_DANCERS] = {0}; MillisecMotorDataStruc MotorData[NUM_OF_MOTORS] = {0}; MillisecMotorDataStruc SpeedSetPending[NUM_OF_MOTORS] = {0}; MillisecMotorDataStruc PT100Data[MAX_TEMPERATURE_SENSOR_ID] = {0}; /******************** GLOBAL PARAMETERS ********************************************/ Mailbox_Handle MillisecMsgQ = NULL; Mailbox_Handle MotorsMsgQ[NUM_OF_MOTORS] = {NULL}; bool MillisecRestart; static GateMutex_Handle gateMillisecDB; uint32_t Millisec_timerBase = TIMER1_BASE; //Timer handle /******************** Functions ********************************************/ uint32_t Control_Delta_Position_Pass(uint32_t Current_Read,uint32_t Previous_Read); //********************************************************************** /******************** CODE ********************************************/ //********************************************************************** uint32_t MSBacklog[200]={0}; uint8_t Motor_Id[200]={0}; uint16_t MsecLogindex = 0; void MillisecInit(void) { Error_Block eb; int i; Error_init(&eb); MillisecMsgQ = Mailbox_create(sizeof(MillisecMessageStruc), 20, NULL,&eb); for (i=0;i<NUM_OF_MOTORS;i++) { MotorsMsgQ[i] = Mailbox_create(sizeof(MillisecMotorDataStruc), 5, NULL,&eb); } MillisecRestart = false; gateMillisecDB = GateMutex_create(NULL, &eb); if (gateMillisecDB == NULL) { System_abort("Could not create USB Wait gate"); } ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); ROM_TimerConfigure(Millisec_timerBase, TIMER_CFG_PERIODIC); // 32 bits Timer //TimerIntRegister(Millisec_timerBase, TIMER_A, Timer0Isr); // Registering isr ROM_TimerEnable(Millisec_timerBase, TIMER_A); ROM_IntEnable(INT_TIMER1A); ROM_TimerIntEnable(Millisec_timerBase, TIMER_TIMA_TIMEOUT); ADCAcquireInit(); return; } void MillisecStop(void) { MillisecRestart = false; ADCAcquireStop(); } void MillisecStart(void) { MillisecRestart = true; ROM_TimerLoadSet(Millisec_timerBase, TIMER_A,120000/*one millisecond*/); ROM_TimerEnable(Millisec_timerBase, TIMER_A); ROM_IntEnable(INT_TIMER1A); ROM_TimerIntEnable(Millisec_timerBase, TIMER_TIMA_TIMEOUT); ADCAcquireStart(0,1); } uint32_t msec_millisecondCounter = 0; void OneMilliSecondMillisecInterrupt(UArg arg0) { MillisecMessageStruc Message; ROM_IntMasterDisable(); ROM_TimerIntClear(Millisec_timerBase, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt if (MillisecRestart == true) { ROM_TimerLoadSet(Millisec_timerBase, TIMER_A,120000/*one millisecond*/); } else { ROM_TimerDisable(Millisec_timerBase,TIMER_A); ROM_IntMasterEnable(); return; } //send message to the Millisec task Message.messageId = OneMillisec; Message.tick = msec_millisecondCounter++;; Message.msglen = sizeof(MillisecMessageStruc); if (MillisecMsgQ != NULL) Mailbox_post(MillisecMsgQ , &Message, BIOS_NO_WAIT); // // Enable all interrupts. // ROM_IntMasterEnable(); return ; } uint32_t PT100Activity = 0; int32_t MillisecReadFromTempSensor(uint32_t TempSensorId, MSecFptr Callback) { if (TempSensorId >= MAX_TEMPERATURE_SENSOR_ID) return -1; PT100Activity++; //read request PT100Activity++; //get response PT100Activity++; //read request PT100Data[TempSensorId].Callback = Callback; PT100Data[TempSensorId].DataRequired = true; PT100Data[TempSensorId].Active = true; return OK; } //typedef uint32_t (* MSecFptr)(uint32_t deviceID, uint32_t ReadValue); uint32_t MotorActivity = 0; int32_t MillisecSetMotorSpeed(TimerMotors_t MotorId, unsigned long Data, int Length, MSecFptr Callback) { if (MotorId >= NUM_OF_MOTORS) return -1; //========================== MSBacklog[MsecLogindex]=Data; Motor_Id[MsecLogindex]=MotorId; MsecLogindex++; if (MsecLogindex>=199) MsecLogindex = 0; //========================== SpeedSetPending[MotorId].Callback = Callback; SpeedSetPending[MotorId].Data = Data; SpeedSetPending[MotorId].Length = Length; SpeedSetPending[MotorId].DataRequired = false; if (SpeedSetPending[MotorId].Active == false) { MotorActivity++; SpeedSetPending[MotorId].Active = true; } return OK; } int MillisecFlushMsgQ(TimerMotors_t MotorId) { MillisecMotorDataStruc MotorData = {0}; int pend = Mailbox_getNumPendingMsgs(MotorsMsgQ[MotorId]); int i; if (pend) { for (i=0;i<pend;i++) Mailbox_pend(MotorsMsgQ[MotorId] , &MotorData, BIOS_NO_WAIT); } return pend; } int32_t MillisecWriteToMotor(TimerMotors_t MotorId, unsigned long Data, int Length, MSecFptr Callback) { MillisecMotorDataStruc MotorData = {0}; //========================== MSBacklog[MsecLogindex]=Data; Motor_Id[MsecLogindex]=MotorId; MsecLogindex++; if (MsecLogindex>=999) MsecLogindex = 0; //========================== if (MotorId >= NUM_OF_MOTORS) return -1; MotorActivity++; MotorData.Callback = Callback; MotorData.Data = Data; MotorData.Length = Length; MotorData.DataRequired = false; if (MotorsMsgQ[MotorId] != NULL) return Mailbox_post(MotorsMsgQ[MotorId] , &MotorData, BIOS_NO_WAIT); else return false; } int32_t MillisecReadFromMotor(TimerMotors_t MotorId, unsigned long Data, int Length, MSecFptr Callback) { MillisecMotorDataStruc MotorData = {0}; if (MotorId >= NUM_OF_MOTORS) return -1; //========================== MSBacklog[MsecLogindex]=Data; Motor_Id[MsecLogindex]=MotorId; MsecLogindex++; if (MsecLogindex>=999) MsecLogindex = 0; //========================== MotorActivity++; MotorActivity++; MotorData.Callback = Callback; MotorData.Data = Data; MotorData.Length = Length; MotorData.DataRequired = true; if (MotorsMsgQ[MotorId] != NULL) return Mailbox_post(MotorsMsgQ[MotorId] , &MotorData, BIOS_NO_WAIT); else return false; } uint32_t MillisecLoop(uint32_t tick) { uint8_t Motor_i; uint8_t Sensor_i; unsigned int MotorInfo = 0; static int temp=0; //call all modules Millisec functions //test dancers and speed encoders //check all callback units (state machine waiting for completion of a change) bool Ten_msTick, Hundred_msTick, Onesecond_Tick,O900Millisecond_Tick; Ten_msTick = (tick%eTenMillisecond == 0) ?true:false; Hundred_msTick = (tick%eHundredMillisecond == 0) ?true:false; O900Millisecond_Tick = (tick%eOneSecond == 900) ?true:false; Onesecond_Tick = (tick%eOneSecond == 0) ?true:false; //gather Motor data from FPGA //ROM_IntMasterDisable(); #ifndef EVALUATION_BOARD FPGA_GetBusy(); //load the busy motor information to all motors FPGA_Read_limit_Switches_Registers(); //Read_FPGA_GPI_Rgisters();//FPGA_Read_limit_Switches(); #endif temp += MotorActivity; if (MotorActivity) { for (Motor_i = 0;Motor_i < NUM_OF_MOTORS;Motor_i++) { if (MotorDriverResponse[Motor_i].Busy == true) { temp++; continue; } if (MotorData[Motor_i].WaitForData == true) //Read request sent, data is waiting { if (MotorGetFPGAResponse((HardwareMotorType)Motor_i,&MotorInfo) == OK) //got the data from the FPGA { MotorData[Motor_i].WaitForData = false; if (MotorData[Motor_i].Callback) MotorData[Motor_i].Callback(Motor_i,MotorInfo); } MotorActivity--; } if (SpeedSetPending[Motor_i].Active == true) { MotorSendFPGARequest((HardwareMotorType)Motor_i,SpeedSetPending[Motor_i].Data,SpeedSetPending[Motor_i].Length); MotorActivity--; SpeedSetPending[Motor_i].Active = false; if (SpeedSetPending[Motor_i].Callback) SpeedSetPending[Motor_i].Callback(Motor_i,0); } else if (Mailbox_pend(MotorsMsgQ[Motor_i] , &MotorData[Motor_i], BIOS_NO_WAIT)==true) { if (MotorSendFPGARequest((HardwareMotorType)Motor_i,MotorData[Motor_i].Data,MotorData[Motor_i].Length) == OK) //sent the data to the FPGA { if (MotorData[Motor_i].DataRequired == true) { MotorData[Motor_i].WaitForData = true; // mark the motor for data request next round } else { if (MotorData[Motor_i].Callback) MotorData[Motor_i].Callback(Motor_i,0); // call the callback to report execution } } MotorActivity--; } } } //FPGA_GetTempSensorBusy(); if (PT100Activity) { for (Sensor_i = 0;Sensor_i < MAX_TEMPERATURE_SENSOR_ID;Sensor_i++) { //if (TempDriverDriverResponse[Sensor_i].Busy == true) // continue; if (PT100Data[Sensor_i].SyncRequired == true) { TemperatureSendSensorDummyClk((TEMPERATURE_SENSOR_ID_ENUM)Sensor_i); PT100Data[Sensor_i].SyncRequired = false; if (PT100Data[Sensor_i].DataRequired == true) { PT100Data[Sensor_i].WaitForData = true; // mark the motor for data request next round } else { if (PT100Data[Sensor_i].Callback) PT100Data[Sensor_i].Callback(Sensor_i,0); // call the callback to report execution } PT100Activity--; } else if (PT100Data[Sensor_i].WaitForData == true) //Read request sent, data is waiting { if (TemperatureSensorReadFromFPGA_Res((TEMPERATURE_SENSOR_ID_ENUM)Sensor_i) == OK) //got the data from the FPGA { PT100Data[Sensor_i].WaitForData = false; if (PT100Data[Sensor_i].Callback) PT100Data[Sensor_i].Callback(Sensor_i,MotorInfo); } PT100Activity--; } if (PT100Data[Sensor_i].Active == true) { TemperatureSensorReadFromFPGA((TEMPERATURE_SENSOR_ID_ENUM)Sensor_i); PT100Data[Sensor_i].Active = false; if (PT100Data[Sensor_i].DataRequired == true) { PT100Data[Sensor_i].SyncRequired = true; // mark the motor for data request next round } else { if (PT100Data[Sensor_i].Callback) PT100Data[Sensor_i].Callback(Sensor_i,0); // call the callback to report execution } PT100Activity--; } } } Dancer_Data[FEEDER_DANCER] = Read_Dancer_Position(FEEDER_DANCER); Dancer_Data[POOLER_DANCER] = Read_Dancer_Position(POOLER_DANCER); Dancer_Data[WINDER_DANCER] = Read_Dancer_Position(WINDER_DANCER); if (Hundred_msTick) { for (Sensor_i = 0;Sensor_i < MAX_TEMPERATURE_SENSOR_ID;Sensor_i++) MillisecReadFromTempSensor(Sensor_i, NULL); } if (O900Millisecond_Tick) { ADC_TriggerCollection(); } if (Onesecond_Tick) { for (Sensor_i = 0;Sensor_i < MAX_SYSTEM_DISPENSERS;Sensor_i++) CalculateDispenserPressure(Sensor_i); FPGA_GetAllDispensersValveBusyOCD(); Control_WD(ENABLE,50); //activate heaters/dispenser watchdog, 5 seconds } //ROM_IntMasterEnable(); return OK; } /****************************************************************************** * ======== messageTsk ======== * Task for this function is created statically. See the project's .cfg file. * this message task is created statically in system initialization, ******************************************************************************/ void MillisecTask(UArg arg0, UArg arg1) { MillisecMessageStruc Message; //char str[60]; //uint16_t length; //Clock_setTimeout(HostKAClock, 1000); //Clock_start(HostKAClock); MillisecInit(); Millisecond_Task_Handle = Task_self(); while(1) { Mailbox_pend(MillisecMsgQ , &Message, BIOS_WAIT_FOREVER); switch (Message.messageId) { case OneMillisec: MillisecLoop(Message.tick); break; default: break; } } } uint32_t getMotorStatusData(int MotorId) { assert (MotorId < NUM_OF_MOTORS); return MotorStatus_Data[MotorId]; } uint32_t getMotorSpeedData(int MotorId) { assert (MotorId < NUM_OF_MOTORS); return MotorSpeed_Data[MotorId]; } uint32_t getTemperatureSensorData(int SensorId) { assert (SensorId < MAX_TEMPERATURE_SENSOR_ID); return TemperatureSensor_Data[SensorId]; } uint32_t getADCData(int DeviceId) { assert (DeviceId < MAX_ADC_DEVICES); return ADC_Data[DeviceId]; }