Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
sis8300llrfControlTableChannel.h 5.46 KiB
/*
 * m-epics-sis8300llrf
 * Copyright (C) 2014-2015  Cosylab

 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @file sis8300llrfControlTableChannel.h
 * @brief Header file defining the LLRF control table (FF and SP) channel class.
 * @author urojec, ursa.rojec@cosylab.com
 * @date 23.5.2014
 */

#ifndef _sis8300llrfControlTableChannel_h
#define _sis8300llrfControlTableChannel_h

#include "sis8300llrfChannel.h"

/**
 * @brief sis8300 LLRF specific nds::ADIOChannel class that supports ControlTable
 *           setup
 *
 * Each control Table acts as an analog output channel. Channel number corresponds to
 * pulse type.
 */
class sis8300llrfControlTableChannel: public sis8300llrfChannel {
public:
    sis8300llrfControlTableChannel();
    virtual ~sis8300llrfControlTableChannel();

    virtual ndsStatus initialize();

    virtual int tableSet();
    virtual ndsStatus markAllParametersChanged();

    virtual ndsStatus registerHandlers(nds::PVContainers* pvContainers);
    virtual ndsStatus setSamplesCount(asynUser *pasynUser, epicsInt32 value);
    virtual ndsStatus getSamplesCount(asynUser *pasynUser, epicsInt32 *value);
    virtual ndsStatus setFFTableMode(asynUser *pasynUser, epicsInt32 value);
    virtual ndsStatus getFFTableMode(asynUser *pasynUser, epicsInt32 *value);
    virtual ndsStatus setQTable(asynUser* pasynUser, epicsFloat32 *value, size_t nelem);
    virtual ndsStatus getQTable(asynUser* pasynUser, epicsFloat32 *value, size_t nelem, size_t *nIn);
    virtual ndsStatus setITable(asynUser* pasynUser, epicsFloat32 *value, size_t nelem);
    virtual ndsStatus getITable(asynUser* pasynUser, epicsFloat32 *value, size_t nelem, size_t *nIn);
    virtual ndsStatus getRawTable(asynUser *pasynUser, epicsInt32 *value, size_t nelem, size_t *nIn);

protected:
    sis8300llrfdrv_ctrl_table _CtrlTableType; /**< Table type, either SP or FF */
    epicsInt32 *_RawTable;          /**< Holds the table in hw format */
    epicsInt32 _FFTableMode;        /**< Can be hold last (normal) or circular (special operation) */

    epicsInt32 _SamplesCount;       /**< Table size for this pulse type */
    epicsInt32 _MaxSamplesCount;    /**< Maximum allowed number of table elements. Equals to _SamplesCount from Channel group */

    int        _RawTableChange;     /**< Parameter tracking table changes */
    int        _SamplesCountChange; /** < Parameter Tracking Samples count changes */
    int        _FFTableModeChange;  /** < Parameter tracking FF table mode changes */
    int        _TableSet;           /**< Set to 1 the first time table is written - so that we know table is set up */

    epicsFloat32 *_QTable;          /**< Angle part of the control table */
    epicsFloat32 *_ITable;          /**< Magnitude part of the control table */

    int _QNelm;                     /**< Number of elements in the Angle table */
    int _INelm;                     /**< Number of elements in the angle table */

    static epicsFloat32 _ConvFact;  /**< For converting samples from/to device's fixed point to/from double */
    
    /* write to hardware */
    virtual ndsStatus writeToHardware();

    /* for asynReasons */
    static std::string PV_REASON_Q_TABLE;
    static std::string PV_REASON_I_TABLE;
    static std::string PV_REASON_RAW_TABLE;
    static std::string PV_REASON_FF_TABLE_MODE;

    int _interruptIdQTable;
    int _interruptIdITable;
    int _interruptIdRawTable;
    int _interruptIdFFTableMode;

    virtual inline void fillTable();
    virtual void freeBuffers();

    virtual ndsStatus onEnterError(nds::ChannelStates from, nds::ChannelStates to);
};


/**
 * @brief Control Table Channel Special Operating mode constructor.
 *
 * This channel allows abusing the I and Q table as Mag and angle table for
 * purposes of Magnitude and angle control
 *
 * This channel is alwasy loaded as the last one in the FF or SP control table channel group.
 * Loading of this channel is not optional
 */
class sis8300llrfControlTableChannelSpecOp: public sis8300llrfControlTableChannel {
public:
    sis8300llrfControlTableChannelSpecOp();
    virtual ~sis8300llrfControlTableChannelSpecOp();

    virtual ndsStatus initialize();

    virtual ndsStatus registerHandlers(nds::PVContainers* pvContainers);
    virtual ndsStatus setAngleTable(asynUser* pasynUser, epicsFloat32 *value, size_t nelem);
    virtual ndsStatus getAngleTable(asynUser* pasynUser, epicsFloat32 *value, size_t nelem, size_t *nIn);
    virtual ndsStatus setMagnitudeTable(asynUser* pasynUser, epicsFloat32 *value, size_t nelem);
    virtual ndsStatus getMagnitudeTable(asynUser* pasynUser, epicsFloat32 *value, size_t nelem, size_t *nIn);

protected:
    sis8300llrfdrv_Qmn _MagQmn;     /**< Magnitude format on the device is different for SP and FF magnitude */

    static std::string PV_REASON_ANGLE_TABLE;
    static std::string PV_REASON_MAG_TABLE;

    int _interruptIdAngleTable;
    int _interruptIdMagTable;
};

#endif /* _sis8300llrfControlTableChannel_h */