aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml.cs
blob: 7825bf587bcfb0256daa4a1b6bd89979f19794e3 (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.UI.Views
{
    /// <summary>
    /// Interaction logic for ResolvedBugsView.xaml
    /// </summary>
    public partial class ResolvedIssuesView : UserControl
    {
        public ResolvedIssuesView()
        {
            InitializeComponent();
        }
    }
}
/************************************************************************************************************************
 * Millisec.c
 * Millisec module
 *
 * The millisec task is called once every 1 millisecond to gather data from the FPGA crucial modules,
 * so it will be ready for the Millisec operations. it is called 300 (TBD, configurable)
 * microsecond before the Millisec task, so that the data will be ready for the Millisec handling.
 * the ,millisecond task holds the pointer to a double buffer of results, so that the Millisec will handle the
 * most updated data, without disturbing data gathering
 *
 **************************************************************************************************************************/

////////////////////////////////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 "MillisecTask.h"
#include <driverlib/timer.h>
#include <inc/hw_ints.h>

#include "drivers/adc_sampling/adc.h"
#include "control.h"

#include "drivers/Motors/Motor.h"
#include "drivers/Danser_SSI/SSI_Comm.h"
#include "drivers/Heater/TemperatureSensor.h"
#include "drivers/FPGA/FPGA_SPI_Comm.h"

/******************** Definitions  ********************************************/
#define INVALID_MSG_ID    0xFFFF
#define MAX_TANGO_CONTROL_DEVICES 200
/******************** STRUCTURES AND ENUMs  ********************************************/
typedef struct MillisecMotorData
{
    bool WaitForData;
    bool DataRequired;
    MSecFptr Callback;
    unsigned long Data;
    int Length;
    bool Active;
}MillisecMotorDataStruc;
typedef enum
{
    OneMillisec,
}MillisecMessages;

typedef struct MillisecMessage{
    uint16_t messageId;
    uint16_t msglen;
    uint32_t tick;
    uint8_t messageData[20];
}MillisecMessageStruc;

uint32_t  ADC_Data[MAX_ADC_DEVICES] = {0};
uint32_t  TemperatureSensor_Data[MAX_TEMPERATURE_SENSOR_ID] = {0};
uint32_t  MotorSpeed_Data[NUM_OF_MOTORS] = {0};
uint32_t  MotorStatus_Data[NUM_OF_MOTORS] = {0};
uint32_t  MotorPosition_Data[NUM_OF_MOTORS] = {0};
bool      MotorBusy_Data[NUM_OF_MOTORS] = {true};
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                MillisecDatalog[MAX_TANGO_CONTROL_DEVICES];
uint32_t        Millisec_timerBase = TIMER1_BASE;        //Timer handle
/******************** Functions  ********************************************/
uint32_t Control_Delta_Position_Pass(uint32_t Current_Read,uint32_t Previous_Read);
//**********************************************************************
/******************** CODE  ********************************************/
//**********************************************************************

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), 6, NULL,&eb);
    }

    MillisecRestart = false;

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

    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*/);
    ADCAcquireStart(0,1);
}


void OneMilliSecondMillisecInterrupt(UArg arg0)
{
    MillisecMessageStruc Message;
    ROM_IntMasterDisable();
    if (MillisecRestart == true)
    {
        ROM_TimerLoadSet(Millisec_timerBase, TIMER_A,120000/*one millisecond*/);
    }
    else
        ROM_TimerDisable(Millisec_timerBase,TIMER_A);

    //send message to the Millisec task
    Message.messageId = OneMillisec;
    Message.tick = UsersysTickGet();
    Message.msglen = sizeof(MillisecMessageStruc);
    if (MillisecMsgQ != NULL)
        Mailbox_post(MillisecMsgQ , &Message, BIOS_NO_WAIT);

    ROM_TimerIntClear(Millisec_timerBase, TIMER_TIMA_TIMEOUT);  // Clear the timer interrupt
    //
    // Enable all interrupts.
    //
    ROM_IntMasterEnable();
    return ;
}
int32_t MillisecWriteToTempSensor(uint32_t TempSensorId, unsigned long Data, int Length, MSecFptr Callback)
{
    if (TempSensorId >= MAX_TEMPERATURE_SENSOR_ID) return -1;
    PT100Data[TempSensorId].Callback = Callback;
    PT100Data[TempSensorId].Data = Data;
    PT100Data[TempSensorId].Length = Length;
    PT100Data[TempSensorId].DataRequired = false;
    PT100Data[TempSensorId].Active = true;

    return OK;
}
int32_t MillisecReadFromTempSensor(uint32_t TempSensorId, unsigned long Data, int Length, MSecFptr Callback)
{
    if (TempSensorId >= MAX_TEMPERATURE_SENSOR_ID) return -1;
    PT100Data[TempSensorId].Callback = Callback;
    PT100Data[TempSensorId].Data = Data;
    PT100Data[TempSensorId].Length = Length;
    PT100Data[TempSensorId].DataRequired = true;
    PT100Data[TempSensorId].Active = true;

    return OK;
}
//typedef  uint32_t (* MSecFptr)(uint32_t deviceID, uint32_t ReadValue);
int32_t MillisecSetMotorSpeed(TimerMotors_t MotorId, unsigned long Data, int Length, MSecFptr Callback)
{
    if (MotorId >= NUM_OF_MOTORS) return -1;
    SpeedSetPending[MotorId].Callback = Callback;
    SpeedSetPending[MotorId].Data = Data;
    SpeedSetPending[MotorId].Length = Length;
    SpeedSetPending[MotorId].DataRequired = false;
    SpeedSetPending[MotorId].Active = true;

    return OK;
}
int32_t MillisecWriteToMotor(TimerMotors_t MotorId, unsigned long Data, int Length, MSecFptr Callback)
{
    MillisecMotorDataStruc MotorData = {0};
    if (MotorId >= NUM_OF_MOTORS) return -1;
    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;
    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)
{
    TimerMotors_t Motor_i;
    int Sensor_i;
    unsigned int MotorInfo = 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;
    Ten_msTick      =   (tick%eTenMilliSecond == 0)      ?true:false;
    Hundred_msTick  =   (tick%eHundredMillisecond == 0)  ?true:false;
    Onesecond_Tick  =   (tick%eOneSecond == 0)           ?true:false;

    //gather Motor data from FPGA
    FPGA_GetBusy();  //load the busy motor information to all motors
    for (Motor_i = 0;Motor_i < NUM_OF_MOTORS;Motor_i++)
    {
        if (MotorDriverResponse[Motor_i].Busy == true)
            continue;
        if (MotorData[Motor_i].WaitForData == true) //Read request sent, data is waiting
        {
            if (MotorGetFPGAResponse(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);
            }
        }
        if (SpeedSetPending[Motor_i].Active == true)
        {
            MotorSendFPGARequest(Motor_i,SpeedSetPending[Motor_i].Data,SpeedSetPending[Motor_i].Length);
            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(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
                }
            }
        }
    }
    //FPGA_GetTempSensorBusy();
    for (Sensor_i = 0;Sensor_i < NUM_OF_MOTORS;Sensor_i++)
    {
        //if (TempDriverDriverResponse[Sensor_i].Busy == true)
        //    continue;
        if (PT100Data[Sensor_i].WaitForData == true) //Read request sent, data is waiting
        {
            if (SPIGetFPGAResponse(Sensor_i,&MotorInfo) == OK) //got the data from the FPGA
            {
                PT100Data[Sensor_i].WaitForData = false;
                if (PT100Data[Sensor_i].Callback)
                    PT100Data[Sensor_i].Callback(Sensor_i,MotorInfo);
            }
        }
        if (PT100Data[Sensor_i].Active == true)
        {
            SPISendFPGARequest(Sensor_i,PT100Data[Sensor_i].Data,PT100Data[Sensor_i].Length);
            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
            }
        }
    }
    Dancer_Data[FEEDER_DANCER] = Read_Dancer_Position(FEEDER_DANCER);
    if (Hundred_msTick)
    {
    }
#ifdef EVALUATION_BOARD

    /* this cannot be done within one millisecond, and not needed
     * instead, check if there is a motor waiting with data to send or read request
     * MotorSpeed_Data[MOTOR_DRYER_DRIVING] = MotorGetSpeedFromFPGA(MOTOR_DRYER_DRIVING);
    MotorStatus_Data[MOTOR_DRYER_DRIVING] = MotorGetStatusFromFPGA(MOTOR_DRYER_DRIVING);
    MotorSpeed_Data[MOTOR_SCREW] = MotorGetSpeedFromFPGA(MOTOR_SCREW);
    MotorStatus_Data[MOTOR_SCREW] = MotorGetStatusFromFPGA(MOTOR_SCREW);
    MotorSpeed_Data[MOTOR_WINDER] = MotorGetSpeedFromFPGA(MOTOR_WINDER);
    MotorStatus_Data[MOTOR_WINDER] = MotorGetStatusFromFPGA(MOTOR_WINDER);
    MotorSpeed_Data[MOTOR_LDRIVING] = MotorGetSpeedFromFPGA(MOTOR_LDRIVING);
    MotorStatus_Data[MOTOR_LDRIVING] = MotorGetStatusFromFPGA(MOTOR_LDRIVING);
    MotorSpeed_Data[MOTOR_RDRIVING] = MotorGetSpeedFromFPGA(MOTOR_RDRIVING);
    MotorStatus_Data[MOTOR_RDRIVING] = MotorGetStatusFromFPGA(MOTOR_RDRIVING);*/
    //gather Dancer data from FPGA
    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);
    //gather data from FPGA
    if (Ten_msTick)
    {
        MotorPosition_Data[MOTOR_SCREW] = MotorGetPositionFromFPGA(MOTOR_SCREW);
        MotorPosition_Data[MOTOR_RDRIVING] = MotorGetPositionFromFPGA(MOTOR_RDRIVING);
    }
    if (Hundred_msTick)
    {
        int adc_i;
        for (adc_i = 0; adc_i < MAX_ADC_DEVICES ; adc_i++)
            ADC_Data[adc_i] = ADC_GetReading(adc_i);
        //trigger the ADC collection - check and set priorities to make sure handling timing is correct.
        //we might want to call it from the task, after execution of other tasks!!!
        ADC_TriggerCollection();

        TEMPERATURE_SENSOR_ID_ENUM pt100_i;
        for (pt100_i = 0; pt100_i < (int)MAX_TEMPERATURE_SENSOR_ID ; pt100_i++)
            TemperatureSensor_Data[pt100_i] = TemperatureSensorReadFromFPGA(pt100_i);
        MotorGetnBusyFromFPGA(); // get all motors nBusy bit status from the FPGAs
        TimerMotors_t motor_i;
        for (motor_i = 0; motor_i < NUM_OF_MOTORS ; motor_i++)
        {
            MotorBusy_Data[motor_i] = MotorGetnBusyState(motor_i);
            if (MotorBusy_Data[motor_i] == false) //can get data
            {
                MotorSpeed_Data[motor_i] = MotorGetSpeedFromFPGA(motor_i);
                MotorStatus_Data[motor_i] = MotorGetStatusFromFPGA(motor_i);
            }
        }
    }
#endif
    //gather data from FPGA

    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();

    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];
}