aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml.cs
blob: 07d01296659f134d87e321a75110e42c7f2d6da4 (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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Tango.MachineStudio.MachineDesigner.Views
{
    /// <summary>
    /// Interaction logic for MachineDetailsView.xaml
    /// </summary>
    public partial class MachineDetailsView : UserControl
    {
        public MachineDetailsView()
        {
            InitializeComponent();
        }
    }
}
/************************************************************************************************************************
 * control.c
 * Control module
 *
 * The control module is hardware agnostic, not related to a specific hardware module, to enable it to deal with hardware and system changes easily.
 * The control module contains a high priority task that connects the hardware drivers
 * below to the control algorithms of the high level system modules above.
 *
 * The control task is invoked by a message from a 1 millisecond timer interrupt.
 * The module is based on system components registered in the control module, supplying callback hooks for information gathering and distribution.
 * All control clients (drivers and modules) will not perform long procedures that will block the control task.
 *
 * Control interfaces:
 * System Devices list:
 *
 * All control system input devices   will be listed in a system-shared enumareted list, to create a common language between the modules and the drivers.
 * (The list will include all hardware devices, but for this module only control input devices are valid)
 * Drivers:
 * Device registration: a driver that initializes a control input device will call the ControlDeviceRegister function with the deviceId,
 * and a control callback hook. This callback is called with a deviceId as the parameter, and returns an unsigned 32bit integer
 * as a read value and a call status. The callback will be a non-blocking call, and will indicate in the status value if the data is valid.
 *
 * It is the responsibility of the device driver to update the control information according to the module hardware requirements.
 * If the polling of the information is immediate, it can be collected at the callback call (e.g. local GPI).
 *
 * Module registration � control:  a module is registering to receive the value of the input from a specific device.
 * The module indicates what will be the desired frequency of the device polling (in milliseconds).
 * It supplies a callback routine that will receive the deviceId, the control value status and the control value.
 * The callback will be a non-blocking call.
 * The polling frequency is one of a specific list of frequencies: 1/10/100/1000 Hz. (others - TBD)
 *
 *
 * Registering a request for control information from a device that is not registered will be rejected.
 * The device registration process must be performed before module registration process.
 *
 * Unregistering: when control information is not needed, the module will unregister the device polling request from the control module.
 * There is a separate call for control hooks and for report hooks.
 * The unregistering command contains the callback function pointer, to enable distribution of control
 * information of the same device to more than one destination.
 *
 **************************************************************************************************************************/

////////////////////////////////State machine operation////////////////////////////////////
//the state machine operation is used to operate in runtime correct profile flow execution
//by recieved esign flow of the user from the UI
///////////////////////////////////////////////////////////////////////////////////////////
#include "include.h"
#include "Modules/General/GeneralHardware.h"

#include <driverlib/timer.h>
#include <inc/hw_ints.h>

#include "drivers/adc_sampling/adc.h"
#include "Drivers/Peripheral_GPIO/GPIO.h"
#include "control.h"
#include "MillisecTask.h"
/******************** Definitions  ********************************************/
#define INVALID_MSG_ID    0xFFFF
#define MAX_TANGO_CONTROL_DEVICES 80
/******************** STRUCTURES AND ENUMs  ********************************************/


typedef struct
{
  uint32_t PartId;  // the identity of the inspected/controlled part in the Devices enum.
  bool ControlActive;
  uint32_t Parameter1;
  uint32_t Parameter2;
  uint32_t IfIndex;
  DataReadCBFunction ControlDataReadPtr;
  ControlCBFunction ControlCallbackPtr;
  CTRL_TIMING_ENUM ControlTiming;
  uint32_t lastStatus;
}ControlDeviceStruc;

typedef enum
{
    OneMillisec,
}controlMessages;

typedef struct ControlMessage{
    uint16_t messageId;
    uint16_t msglen;
    uint32_t tick;
    uint8_t messageData[20];
}ControlMessageStruc;

int ControlPhaseDelay = 300; //the control task enters only after data gathering in the millisecond task is finished.
//this parameters defines how many microseconds in the delay. it is used only on starting the control loop on the first time
/******************** GLOBAL PARAMETERS  ********************************************/
Mailbox_Handle          ControlMsgQ = NULL;
bool                    ControlRestart;
static GateMutex_Handle gateControlDB;
Task_Handle Control_Task_Handle;
ControlDeviceStruc      ControlArray[MAX_TANGO_CONTROL_DEVICES];
uint32_t                ControlDatalog[MAX_TANGO_CONTROL_DEVICES];
uint16_t ControlBacklog[1000]={0};
uint16_t backlogindex = 0;
uint32_t        Control_timerBase = TIMER0_BASE;        //Timer handle
/******************** Functions  ********************************************/
void OneMilliSecondFunction(UArg arg0);

//**********************************************************************
/******************** CODE  ********************************************/
//**********************************************************************
uint32_t TemplateDataReadCBFunction (uint32_t deviceID, uint32_t Parameter1, uint32_t Parameter2)
{
    return 0;
}



void ControlInit(void)
{
    int Device_i;
    Error_Block eb;

    //Mailbox_Params_init(&ControlMsgQ);
    ControlMsgQ = Mailbox_create(sizeof(ControlMessageStruc), 20, NULL,NULL);

    ControlRestart = false;

    memset(ControlDatalog,0,sizeof(uint32_t)*MAX_TANGO_CONTROL_DEVICES);

    for (Device_i = 0; Device_i < MAX_TANGO_CONTROL_DEVICES; Device_i++)
    {
        ControlArray[Device_i].ControlActive = false;
        ControlArray[Device_i].ControlCallbackPtr = NULL;
        ControlArray[Device_i].ControlDataReadPtr = NULL;
        ControlArray[Device_i].ControlTiming = eNoControl;
    }
    gateControlDB = GateMutex_create(NULL, &eb);
    if (gateControlDB == NULL)
    {
        System_abort("Could not create USB Wait gate");
    }

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    ROM_TimerConfigure(Control_timerBase, TIMER_CFG_PERIODIC);   // 32 bits Timer
    //TimerIntRegister(Control_timerBase, TIMER_A, Timer0Isr);    // Registering  isr
    ROM_TimerEnable(Control_timerBase, TIMER_A);
    ROM_IntEnable(INT_TIMER0A);
    ROM_TimerIntEnable(Control_timerBase, TIMER_TIMA_TIMEOUT);

    //ADCAcquireInit();

    return;
}
void ControlStop(void)
{
    ControlRestart = false;
    ADCAcquireStop();
}
uint32_t ControlActivityLed( uint32_t Parameter1, uint32_t Parameter2)
{
    static bool flag = false;
    if (flag==true)
    {
        COMM_RED_LED_ON;
        flag = false;
    }
    else
    {
        COMM_RED_LED_OFF;
        flag = true;
    }
return OK;
}
uint32_t ControlEmptyCBFunction(uint32_t IfIndex, uint32_t ReadValue)
{
    return OK;
}

void ControlStart(void)
{
    if (ControlRestart == false)
    {
        ControlRestart = true;
        MillisecStart();
        ROM_TimerLoadSet(Control_timerBase, TIMER_A,120000+(ControlPhaseDelay*120)/*one millisecond*/);
        TimerEnable(Control_timerBase, TIMER_A);

        ADCAcquireStart(0,1);
        AddControlCallback( ControlEmptyCBFunction,  eHundredMillisecond, ControlActivityLed,0, 0, 0 );

    }
}

/************************************************************************************************************************************************
 * the control task reads the data from the devices every millisecond.
 * (the data might be old data, if it is polled in a slower rate)
 * for every polled device, there is a need to add a Data read callback, with a device id. the read value is always 32bits unsigned integer
 * if there is a need to run a control function based on the read data, then the hardware module will add a control function, specifying the control calling rate
 * both these callbacks can be removed. if a new call is arriving, it invalidates the previous one (no dual control or data)
 *
 ***************************************************************************************************************************************************/
uint32_t  AddControlCallback( ControlCBFunction Callback, CTRL_TIMING_ENUM CtrlFrequency, DataReadCBFunction DriverfPtr, uint32_t IfIndex, uint32_t Parameter1, uint32_t Parameter2 )
{
    assert(Callback);
    assert(DriverfPtr);
    unsigned int key;

    uint32_t device_i;
    uint32_t deviceId = 0xFFFFFFFF;
    for(device_i = 0;device_i < MAX_TANGO_CONTROL_DEVICES;device_i++)
    {
        if (ControlArray[device_i].ControlActive == false)
        {
            deviceId = device_i;
            break;
        }
    }
    if (deviceId == 0xFFFFFFFF)
        return 0xFFFFFFFF;
    key = GateMutex_enter(gateControlDB);
    ControlArray[deviceId].ControlTiming = CtrlFrequency;
    ControlArray[deviceId].ControlCallbackPtr = Callback;
    ControlArray[deviceId].ControlActive = true;
    ControlArray[deviceId].ControlDataReadPtr = DriverfPtr;
    ControlArray[deviceId].Parameter1 = Parameter1;
    ControlArray[deviceId].Parameter2 = Parameter2;
    ControlArray[deviceId].IfIndex = IfIndex;
    GateMutex_leave(gateControlDB, key);

    return deviceId;

}
int     RemoveControlCallback(uint32_t deviceId , ControlCBFunction Callback)
{
    assert(deviceId < MAX_TANGO_CONTROL_DEVICES);
    unsigned int key;

    if (Callback == ControlArray[deviceId].ControlCallbackPtr)
    {
        key = GateMutex_enter(gateControlDB);
        ControlArray[deviceId].ControlTiming = eNoControl;
        ControlArray[deviceId].ControlCallbackPtr = NULL;
        ControlArray[deviceId].ControlDataReadPtr = NULL;
        ControlArray[deviceId].ControlActive = false;
        GateMutex_leave(gateControlDB, key);
        return OK;
    }
    else
        return ERROR;

}

uint32_t millisecondCounter = 0;
void OneMilliSecondControlInterrupt(UArg arg0)
{
    ControlMessageStruc Message;
    ROM_IntMasterDisable();
    if (ControlRestart == true)
    {
        ROM_TimerLoadSet(Control_timerBase, TIMER_A,120000/*one millisecond*/);
    }
    else
        ROM_TimerDisable(Control_timerBase, TIMER_A);

    //send message to the control task
    Message.messageId = OneMillisec;
    Message.tick = millisecondCounter++;
    Message.msglen = sizeof(ControlMessageStruc);
    if (ControlMsgQ != NULL)
        Mailbox_post(ControlMsgQ , &Message, BIOS_NO_WAIT);
    if (millisecondCounter == 1000000000)
        millisecondCounter = 0;
    ROM_TimerIntClear(Control_timerBase, TIMER_TIMA_TIMEOUT);  // Clear the timer interrupt
    //
    // Enable all interrupts.
    //
    ROM_IntMasterEnable();
    return ;
}

uint32_t ControlLoop(uint32_t tick)
{
    //call all modules control functions
    //test dancers and speed encoders
    //check all callback units (state machine waiting for completion of a change)
    uint32_t Device_i;
    bool Ten_msTick, Hundred_msTick, Onesecond_Tick,Tick98,Tick998;
    Ten_msTick      =   (tick%eTenMilliSecond == 0)      ?true:false;
    Hundred_msTick  =   (tick%eHundredMillisecond == 0)  ?true:false;
    Onesecond_Tick  =   (tick%eOneSecond == 0)           ?true:false;
    Tick98          =   (tick%eHundredMillisecond == 99) ?true:false;
    Tick998         =   (tick%eOneSecond == 996)         ?true:false;

    for (Device_i = 0; Device_i < MAX_TANGO_CONTROL_DEVICES;Device_i++)
    {
        if (ControlArray[Device_i].ControlActive)
        {
            ControlBacklog[backlogindex]=Device_i;
            if ( ++backlogindex >= 999)
                backlogindex = 0;
            switch (ControlArray[Device_i].ControlTiming)
            {
                case eOneMillisecond:
                    if(ControlArray[Device_i].ControlDataReadPtr)
                        ControlDatalog[Device_i] = ControlArray[Device_i].ControlDataReadPtr( ControlArray[Device_i].Parameter1,ControlArray[Device_i].Parameter2);
                    else
                        LOG_ERROR (Device_i, "Invalid callback ptr");
                    if(ControlArray[Device_i].ControlCallbackPtr)
                        ControlArray[Device_i].ControlCallbackPtr(ControlArray[Device_i].IfIndex, ControlDatalog[Device_i]);
                    else
                        LOG_ERROR (Device_i, "Invalid callback ptr");
                    break;
                case eTenMilliSecond:
                    if (Ten_msTick)
                    {
                        if(ControlArray[Device_i].ControlDataReadPtr)
                            ControlDatalog[Device_i] = ControlArray[Device_i].ControlDataReadPtr( ControlArray[Device_i].Parameter1,ControlArray[Device_i].Parameter2);
                        else
                            LOG_ERROR (Device_i, "Invalid callback ptr");
                        if(ControlArray[Device_i].ControlCallbackPtr)
                            ControlArray[Device_i].ControlCallbackPtr(ControlArray[Device_i].IfIndex, ControlDatalog[Device_i]);
                        else
                            LOG_ERROR (Device_i, "Invalid callback ptr");
                    }
                    break;
                case eHundredMillisecond:
                    if (Tick98)
                    {
                        //there is a need to trigger the data collection from FPGA, from I2C or from ADC 1.5 milliseconds to collect the data
                        if(ControlArray[Device_i].ControlDataReadPtr)
                            ControlDatalog[Device_i] = ControlArray[Device_i].ControlDataReadPtr( ControlArray[Device_i].Parameter1,ControlArray[Device_i].Parameter2);
                        else
                            LOG_ERROR (Device_i, "Invalid callback ptr");
                    }
                    if (Hundred_msTick)
                    {
                        //there is a need to trigger the data collection from FPGA, from I2C or from ADC 1.5 milliseconds to collect the data
                        if(ControlArray[Device_i].ControlCallbackPtr)
                            ControlArray[Device_i].ControlCallbackPtr(ControlArray[Device_i].IfIndex, ControlDatalog[Device_i]);
                        else
                            LOG_ERROR (Device_i, "Invalid callback ptr");
                    }
                    break;
                case eOneSecond:
                    if (Tick998)
                    {
                        if(ControlArray[Device_i].ControlDataReadPtr)
                            ControlDatalog[Device_i] = ControlArray[Device_i].ControlDataReadPtr( ControlArray[Device_i].Parameter1,ControlArray[Device_i].Parameter2);
                        else
                            LOG_ERROR (Device_i, "Invalid callback ptr");
                    }
                    if (Onesecond_Tick)
                    {
                        if(ControlArray[Device_i].ControlCallbackPtr)
                            ControlArray[Device_i].ControlCallbackPtr(ControlArray[Device_i].IfIndex, ControlDatalog[Device_i]);
                        else
                            LOG_ERROR (Device_i, "Invalid callback ptr");
                    }
                    break;
                default:
                    LOG_ERROR (ControlArray[Device_i].ControlTiming, "Invalid control timing value");
                    break;
            } //switch
        } //if control active
    }  //for

    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 controlTask(UArg arg0, UArg arg1)
{
    ControlMessageStruc Message;
    //char str[60];
    //uint16_t length;
    //Clock_setTimeout(HostKAClock, 1000);
    //Clock_start(HostKAClock);
    Control_Task_Handle = Task_self();

    while(1)
    {
        Mailbox_pend(ControlMsgQ , &Message, BIOS_WAIT_FOREVER);
        switch (Message.messageId)
        {
            case OneMillisec:
                ControlLoop(Message.tick);
                break;
            default:
                break;
        }
    }
}