Changeset 11852 for trunk/FACT++


Ignore:
Timestamp:
08/09/11 00:03:13 (13 years ago)
Author:
tbretz
Message:
This is the first step to get a working and stable Bias control.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/biasctrl.cc

    r11775 r11852  
    2525class ConnectionBias : public ConnectionUSB
    2626{
    27     vector<char> fBuffer;
     27    vector<uint8_t> fBuffer;
    2828
    2929    bool fIsVerbose;
     
    3838    enum Command_t
    3939    {
    40         kCmdReset = 0,
    41         kCmdRead  = 1,
    42         kCmdWrite = 3
     40        kCmdReset      = 0,
     41        kCmdRead       = 1,
     42        kCmdGlobalSet  = 2,
     43        kCmdChannelSet = 3,
     44        kCmdPrint      = 4
    4345    };
    44 
    4546
    4647     // Resistance in Ohm for voltage correction
     
    4950protected:
    5051
    51     vector<uint16_t> fVolt;        // Voltage in DAC units
     52    vector<uint16_t> fVolt;        // Voltage in DAC units (12bit = 90V)
    5253    vector<uint16_t> fRefVolt;
    5354
    54     vector<uint16_t> fCurrent;     // Current in ADC units
    55     vector<uint16_t> fRefCurrent;
    56 
    57     vector<bool>     fOC;
     55    vector<int16_t>  fCurrent;     // Current in ADC units (12bit = 5mA)
     56    vector<int16_t>  fRefCurrent;
     57
    5858    vector<bool>     fPresent;
    5959
    60     bool fResetHit;
     60    int fWrapCounter;
     61
    6162
    6263    virtual void UpdateA()
    6364    {
    64         if (!fIsVerbose)
    65             return;
    66 
    67         for (int c=0; c<kNumChannels; c++)
    68         {
    69             Out() << setw(2) << c << ":";
    70             for (int b=0; b<kNumBoards; b++)
    71                 Out() << " " << setprecision(2) << fixed << setw(5) << fCurrent[b+c*kNumBoards];
    72             Out() << endl;
    73         }
    7465    }
    7566
    7667private:
    77     void HandleReceivedData(const bs::error_code& err, size_t bytes_received, int /*type*/)
    78     {
     68    void HandleReceivedData(const bs::error_code& err, size_t bytes_received, int type)
     69    {
     70        if (type==kCmdPrint && bytes_received==0 && !err)
     71        {
     72            Print();
     73            return;
     74        }
     75
    7976        // Do not schedule a new read if the connection failed.
    8077        if (bytes_received==0 || err)
     
    106103        if (fIsVerbose)
    107104        {
    108             Out() << endl << kBold << "Data received:" << endl;
    109             Out() << Converter::GetHex<uint8_t>(fBuffer, 32) << endl;
    110         }
    111 
    112         int wrapcnt = -1;
    113 
    114         // === Check/update all wrap counter ===
    115         for (unsigned int i=0; i<fBuffer.size(); i += 3)
    116         {
    117             const int old = wrapcnt;
    118             wrapcnt = (fBuffer[i]>>4)&7;
    119 
    120             if (wrapcnt==-1 || (old+1)%8 == wrapcnt)
    121                 continue;
    122 
    123             Error("WrapCnt wrong");
    124             // Error receiving proper answer!
    125             return;
    126         }
    127 
    128         // Success with received answer
    129 
    130         if (fBuffer.size()!=kNumChannels*3)
    131             return;
    132 
    133         /*
    134          data[0] = (cmd<<5) | (board<<1) | (((channel&16)>>4) & 1);
    135          data[1] = (channel<<4) | (cmdval>>8);
    136          data[2] = val&0xff;
    137          */
    138 
    139         // ################## Read all channels status ##################
    140 
    141         // Evaluate data returned from crate
    142         for (int i=0; i<kNumChannels; i++)
    143         {
    144             fOC[i]      =  fBuffer[i*3]&0x80;
    145             fCurrent[i] =  fBuffer[i*3+1] | ((fBuffer[i*3]&0xf)<<8);
    146             fPresent[i] =  fBuffer[i*3+2]&0x70 ? false : true;
    147 
    148             // FIXME FIXME FIXME
    149             fResetHit   = fBuffer[i*3+2] & 0x80;
    150 
    151             if (i==2*kNumChannelsPerBoard+19)
    152                 fOC[i] = false;
    153         }
    154 
    155         UpdateA();
    156     }
    157 
    158     void HandleTransmittedData(size_t n)
    159     {
    160         fBuffer.resize(n);
    161         AsyncRead(ba::buffer(fBuffer));
    162         AsyncWait(fInTimeout, 50, &ConnectionUSB::HandleReadTimeout);
     105            //Out() << endl << kBold << "Data received (size=" << bytes_received << "):" << endl;
     106            //Out() << Converter::GetHex<uint8_t>(fBuffer, 32) << endl;
     107            // FIXME: Check why more is printed than expected
     108        }
     109
     110        const uint16_t command = type&0xf;
     111        const uint16_t id      = type>>4;
     112        const uint16_t status  = (fBuffer[0]>>7)&1;
     113        const uint16_t wrap    = (fBuffer[0]>>4)&7;
     114        const uint16_t ddd     = ((uint16_t(fBuffer[0])&0xf)<<8) | fBuffer[1];
     115        const uint16_t error   = (fBuffer[2]>>4)&0xf;
     116        const uint16_t board   =  fBuffer[2]&0xf;
     117
     118        if (fWrapCounter>=0 && (fWrapCounter+1)%8 != wrap)
     119        {
     120            Error("Corrupted answer (wrap counter not as it ought to be.");
     121            return;
     122        }
     123        fWrapCounter = wrap;
     124
     125        if (error==0x8) // No device
     126        {
     127            ostringstream out;
     128            out << "HV down requested!";
     129            Fatal(out);
     130
     131            GlobalSetDac(0);
     132
     133            // Resynchronize input and output
     134            // SystemReset and status request
     135            PostClose(true);
     136
     137            return;
     138        }
     139
     140        if (command==kCmdReset)
     141        {
     142            if (status==0 && ddd==0 && error==0 && board==0)
     143            {
     144                Message("Reset successfully executed.");
     145                return;
     146            }
     147
     148            Warn("Answer to 'reset' command contains unexpected data.");
     149            return;
     150        }
     151
     152        if (command==kCmdGlobalSet)
     153        {
     154            if (status==0 && ddd==0 && error==0 && board==0)
     155            {
     156                Message("GlobalSet successfully executed.");
     157                return;
     158            }
     159
     160            Warn("Answer to 'global set' command contains unexpected data.");
     161            return;
     162        }
     163
     164        if (command==kCmdRead || command==kCmdChannelSet)
     165        {
     166            if (error==0x7 || error==0xf)
     167            {
     168                fPresent[board] = false;
     169                fCurrent[id]    = 0x8000;
     170                return;
     171            }
     172
     173            if (board!=id/kNumChannelsPerBoard)
     174            {
     175                ostringstream out;
     176                out << "Talked to board " << id/kNumChannelsPerBoard << " but board " <<  board << " answered.";
     177                Error(out);
     178                return;
     179            }
     180
     181            fCurrent[id]    = status ? -ddd : ddd;
     182            fPresent[board] = true;
     183
     184            UpdateA();
     185
     186            return;
     187        }
    163188    }
    164189
     
    166191    void ConnectionEstablished()
    167192    {
     193        fWrapCounter = -1;
     194        fBuffer.resize(3);
     195
     196        SystemReset();
     197        ReadAllChannelsStatus();
    168198    }
    169199
     
    181211            PostClose();
    182212            return;
    183 
    184213        }
    185214
     
    203232    }
    204233
    205 
    206     void SystemReset()
    207     {
    208         PostMessage(GetCmd(0, kCmdReset));
    209     }
    210 
    211234    vector<char> GetCmd(uint16_t id, Command_t cmd, uint16_t dac=0)
    212235    {
     
    239262    void GlobalSetDac(uint16_t dac)
    240263    {
    241         PostMessage(GetCmd(0, kCmdWrite, dac));
    242         /*
    243         // On success
    244         if (fBuffer.size() == 3)
    245         {
    246             for (int i=0; i<MAX_NUM_BOARDS; i++)
    247                 for (int j=0; j<NUM_CHANNELS; j++)
    248                 {
    249                     DAC[i][j]     = SetPoint;
    250                     Volt[i][j]    = Voltage;
    251                     RefVolt[i][j] = Voltage;
    252                 }
    253         }
    254         */
    255     }
    256 
     264        PostMessage(GetCmd(0, kCmdGlobalSet, dac));
     265        AsyncRead(ba::buffer(fBuffer), kCmdGlobalSet);
     266    }
     267
     268    /*
    257269    void SetChannels(const map<uint16_t, uint16_t> &vals)
    258270    {
    259271        if (vals.empty())
    260272            return;
    261 
    262         vector<char> data;
    263273
    264274        // Build and execute commands
     
    266276             it!=vals.end(); it++)
    267277        {
    268             //const uint16_t dac = it->second/90.0*0xfff;
    269 
    270278            // If DAC value unchanged, do not send command
    271279            if (fVolt[it->first] == it->second)
    272280                continue;
    273281
    274             const vector<char> cmd = GetCmd(it->first, kCmdWrite, it->second);
    275             data.insert(data.end(), cmd.begin(), cmd.end());
    276         }
    277 
    278         PostMessage(data);
    279 
    280         /*
    281         // On success
    282         if (Data.size() == Buf.size())
    283         {
    284             for (map<unsigned int, double>::const_iterator it = V.begin(); it != V.end(); ++it) {
    285                 DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = (unsigned int) (it->second/90.0*0x0fff);
    286                 Volt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second;
    287                 RefVolt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second;
    288         }
    289         */
    290     }
     282            const vector<char> cmd = GetCmd(it->first, kCmdChannelSet, it->second);
     283            PostMessage(cmd);
     284            AsyncRead(ba::buffer(fBuffer), kCmdChannelSet|(it->first<<4));
     285        }
     286    }*/
    291287
    292288    /*
     
    314310        fCurrent(kNumChannels),
    315311        fRefCurrent(kNumChannels),
    316         fOC(kNumChannels),
    317         fPresent(kNumChannels)
     312        fPresent(kNumBoards)
    318313    {
    319314        SetLogStream(&imp);
     
    322317    bool GlobalSet(double voltage)
    323318    {
    324         if (voltage<0 || voltage>90)
     319        const uint16_t dac = voltage*4096/90;
     320        if (dac>0xfff)
    325321            return false;
    326322
    327         GlobalSetDac(voltage/90.0*0xfff);
     323        GlobalSetDac(dac);
    328324
    329325        return true;
    330326    }
    331327
     328    bool ChannelSet(uint16_t ch, double voltage)
     329    {
     330        const uint16_t dac = voltage*4096/90;
     331        if (dac>0xfff)
     332            return false;
     333
     334        if (ch>=kNumChannels)
     335            return false;
     336
     337        PostMessage(GetCmd(ch, kCmdChannelSet, dac));
     338        AsyncRead(ba::buffer(fBuffer), kCmdChannelSet|(ch<<4));
     339
     340        return true;
     341    }
     342
    332343    void ReadAllChannelsStatus()
    333344    {
    334         vector<char> data;
    335         data.reserve(kNumChannels*3);
     345        Message("Requesting full system status.");
    336346
    337347        // Prepare command to read all channels
    338348        for (int i=0; i<kNumChannels; i++)
    339             {
    340                 const vector<char> cmd = GetCmd(i, kCmdRead);
    341                 data.insert(data.end(), cmd.begin(), cmd.end());
    342             }
    343 
    344         PostMessage(data);
     349        {
     350            const vector<char> cmd = GetCmd(i, kCmdRead);
     351            PostMessage(cmd);
     352            AsyncRead(ba::buffer(fBuffer), kCmdRead|(i<<4));
     353        }
     354
     355        //vector<char> buf;
     356        //AsyncRead(ba::buffer(buf), kCmdPrint);
    345357    }
    346358
     
    348360    void AdaptVoltages()
    349361    {
    350         map<uint16_t, uint16_t> values;
    351 
    352362        for (int i=0; i<kNumChannels; i++)
    353363        {
    354             if (fRefVolt[i]==0)
     364            if (fRefVolt[i]==0 || fCurrent[i]<0 || fRefCurrent[i]<0)
    355365                continue;
    356366
    357             // Calculate difference and convert ADC units to Amps
    358             const double diffcur = (fRefCurrent[i]-fCurrent[i])*1.22;
     367            // Calculate difference and convert ADC units to Amp
     368            // const double diffcur = (fRefCurrent[i]-fCurrent[i])*5000/4096
     369            //const int32_t diffcur = int32_t(fRefCurrent[i]-fCurrent[i])*5000;
     370            const int32_t diffvolt = (fRefCurrent[i]-fCurrent[i])*5;
    359371
    360372            // Calculate voltage difference
    361             const double diffvolt = diffcur*RESISTOR/1e6;
     373            // #define RESISTOR 1000 // Ohm
     374            //const double diffvolt = diffcur*RESISTOR/1e6;
    362375
    363376            // Calculate new vlaue by onverting voltage difference to DAC units
    364             const int32_t dac = fRefVolt[i] + diffvolt/90.0*0xfff;
    365 
    366             if (dac<0 || dac>0xfff)
     377            //const int32_t dac = fRefVolt[i] + diffvolt*4096/90.0;
     378            int32_t dac = fRefVolt[i] + diffvolt/90;
     379
     380            if (dac<0)
     381                dac = 0;
     382            if (dac>0xfff)
     383                dac = 0xfff;
     384
     385            if (fVolt[i] == dac)
    367386                continue;
    368387
    369             values[i] = fRefVolt[i] + dac;
    370         }
    371 
    372         SetChannels(values);
    373 
    374         /*
    375         static int LastUpdate = 0;
    376         if (time(NULL)-LastUpdate > 5)
    377         {
    378             LastUpdate = time(NULL);
    379             UpdateDIM();
    380         }*/
     388            PostMessage(GetCmd(i, kCmdChannelSet, dac));
     389            AsyncRead(ba::buffer(fBuffer), kCmdChannelSet|(i<<4));
     390        }
     391    }
     392
     393    void SystemReset()
     394    {
     395        Message("Sending system reset.");
     396        PostMessage(GetCmd(0, kCmdReset));
     397        AsyncRead(ba::buffer(fBuffer), kCmdReset);
    381398    }
    382399
     
    389406    {
    390407        fIsVerbose = b;
     408    }
     409
     410    void PrintLine(int b, int ch)
     411    {
     412        Out() << setw(2) << b << "|";
     413
     414        for (int c=ch; c<ch+8; c++)
     415        {
     416            const int id = c+kNumChannelsPerBoard*b;
     417            Out() << " " << setw(7) << abs(fCurrent[id])*5000/4096.;
     418            if (fCurrent[id]<0)
     419                Out() << "!";
     420            else
     421                Out() << " ";
     422        }
     423        Out() << endl;
     424
     425    }
     426    void Print()
     427    {
     428        Out() << dec << setprecision(2) << fixed;
     429        for (int b=0; b<kNumBoards; b++)
     430        {
     431            if (!fPresent[b])
     432            {
     433                Out() << setw(2) << b << "-" << endl;
     434                continue;
     435            }
     436
     437            PrintLine(b,  0);
     438            PrintLine(b,  8);
     439            PrintLine(b, 16);
     440            PrintLine(b, 24);
     441        }
    391442    }
    392443};
     
    469520        if (!fBias.GlobalSet(evt.GetFloat()))
    470521            T::Error("Supplied voltage out of range (0-90)");
     522
     523        return T::GetCurrentState();
     524    }
     525
     526    int SetChannel(const EventImp &evt)
     527    {
     528        if (!CheckEventSize(evt.GetSize(), "SetChannel", 6))
     529            return false;
     530
     531        if (!fBias.ChannelSet(evt.GetUShort(), evt.Get<float>(2)))
     532            T::Error("Value out of range");
    471533
    472534        return T::GetCurrentState();
     
    565627
    566628        AddEvent("REQUEST_STATUS", kStateConnected)
    567             (Wrap(bind(&ConnectionBias::ReadAllChannelsStatus, &fBias)))
     629            (Wrapper(bind(&ConnectionBias::ReadAllChannelsStatus, &fBias)))
    568630            ("");
    569631
    570         AddEvent("SET_GLOBAL", "F:1", kStateConnected)
     632        AddEvent("SET_GLOBAL_VOLTAGE", "F:1", kStateConnected)
    571633            (bind(&StateMachineBias::SetGlobal, this, _1))
    572634            ("");
    573635
     636        AddEvent("SET_CHANNEL_VOLTAGE", "S:1;F:1", kStateConnected)
     637            (bind(&StateMachineBias::SetChannel, this, _1))
     638            ("");
     639
    574640        AddEvent("RESET", kStateConnected)
    575             (Wrap(bind(&ConnectionBias::SystemReset, &fBias)))
     641            (Wrapper(bind(&ConnectionBias::SystemReset, &fBias)))
    576642            ("");
    577643
    578644        AddEvent("SET_REFERENCE_CURRENT", kStateConnected)
    579             (Wrap(bind(&ConnectionBias::SetReferenceCurrent, &fBias)))
     645            (Wrapper(bind(&ConnectionBias::SetReferenceCurrent, &fBias)))
    580646            ("");
    581647
    582648        AddEvent("ADAPT_VOLTAGES", kStateConnected)
    583             (Wrap(bind(&ConnectionBias::AdaptVoltages, &fBias)))
     649            (Wrapper(bind(&ConnectionBias::AdaptVoltages, &fBias)))
    584650            ("");
    585     }
    586 
    587     void SetEndpoint(const string &url)
    588     {
    589         fBias.SetEndpoint(url);
     651
     652        AddEvent("PRINT", kStateConnected)
     653            (Wrapper(bind(&ConnectionBias::Print, &fBias)))
     654            ("");
    590655    }
    591656
    592657    int EvalOptions(Configuration &conf)
    593658    {
    594         SetEndpoint(conf.Get<string>("addr"));
    595 
    596659        fBias.SetVerbose(!conf.Get<bool>("quiet"));
     660
     661        fBias.SetEndpoint(conf.Get<string>("dev"));
     662        T::Message("Setting device to "+fBias.URL());
    597663
    598664        fBias.Connect();
     
    617683    control.add_options()
    618684        ("no-dim,d",      po_bool(),  "Disable dim services")
    619         ("addr,a",        var<string>("ttysS0"),  "Device address of USB port to bias-power supply")
     685        ("dev",           var<string>("FTE00FOH"),  "Device address of USB port to bias-power supply")
    620686        ("quiet,q",       po_bool(),  "Disable printing contents of all received messages (except dynamic data) in clear text.")
    621687        ;
Note: See TracChangeset for help on using the changeset viewer.