LCOV - code coverage report
Current view: top level - apps/xt1121Ctrl - xtChannels.hpp (source / functions) Coverage Total Hit
Test: MagAOX Lines: 90.2 % 41 37
Test Date: 2026-01-03 21:03:39 Functions: 87.5 % 8 7

            Line data    Source code
       1              : /** \file xtChannels.hpp
       2              :   * \brief Utility class for managing Acromag xt12XX digital I/O channels
       3              :   *
       4              :   * \author Jared R. Males (jaredmales@gmail.com)
       5              :   *
       6              :   * \ingroup xt1211Ctrl_files
       7              :   *
       8              :   * History:
       9              :   *  -- Created 2019-04-21 by JRM
      10              :   */
      11              : 
      12              : #ifndef xtChannels_hpp
      13              : #define xtChannels_hpp
      14              : 
      15              : 
      16              : /// Utility class for managing Acromag xt12XX digital I/O channels
      17              : /** Reads and writes input "registers" (uint16_t) for modbus protocol.
      18              :   *
      19              :   * \tparam _numChannels is the number of channels controlled by this device.
      20              :   */
      21              : template<int _numChannels>
      22              : struct xtChannels
      23              : {
      24              :    static constexpr int numChannels = _numChannels; ///< The number of channels controlled by the device
      25              : 
      26              :    static constexpr int numRegisters = _numChannels/4; ///< The number of registers needed for the number of channels.
      27              : 
      28              : protected:
      29              :    bool m_channels[numChannels]; ///< The state of the channels
      30              : 
      31              :    bool m_inputOnly[numChannels]; ///< Control which channels can not be set to output.
      32              : 
      33              : public:
      34              : 
      35              :    /// c'tor
      36              :    /** Sets m_channels and m_inputOnly to false.
      37              :      */
      38              :    xtChannels();
      39              : 
      40              :    /// Set a channel to be input only.
      41              :    /** A channel which is input only will not be sent as an output to the device
      42              :      * regardless of its state in m_channels.
      43              :      *
      44              :      * \returns 0 on success
      45              :      * \returns -1 on error
      46              :      */
      47              :    int setInputOnly( size_t chNo /**< [in] the channel to set to input only */ );
      48              : 
      49              :    /// Set a channel to true
      50              :    /**
      51              :      * \returns 0 on success
      52              :      * \returns -1 on error
      53              :      */
      54              :    int setChannel( size_t chNo /**< [in] the channel to set */ );
      55              : 
      56              :    /// Set a channel to false
      57              :    /**
      58              :      * \returns 0 on success
      59              :      * \returns -1 on error
      60              :      */
      61              :    int clearChannel( size_t chNo /**< [in] the channel to clear */ );
      62              : 
      63              :    /// Clear all channels
      64              :    /**
      65              :      * \returns 0 on success
      66              :      * \returns -1 on error
      67              :      */
      68              :    int clearAll();
      69              : 
      70              :    /// Set registers based on current channel states.
      71              :    /** Respects input only settings.
      72              :      *
      73              :      * \returns 0 on success
      74              :      * \returns -1 on error
      75              :      */
      76              :    int setRegisters( uint16_t registers[numRegisters]  /**< [out] the array of registers to set */ );
      77              : 
      78              :    /// Read channel states from the registers
      79              :    /** This changes m_channels as they are read.
      80              :      *
      81              :      * \returns 0 on success
      82              :      * \returns -1 on error
      83              :      */
      84              :    int readRegisters( uint16_t registers[numRegisters]  /**< [in] the array of registers to read */ );
      85              : 
      86              :    /// Gets the current state of a channel
      87              :    /**
      88              :      * \returns 0 if channel is not set
      89              :      * \returns 1 if channel is set
      90              :      * \returns -1 on error
      91              :      */
      92              :    int channel( size_t chNo  /**< [in] the channel to retrieve */ );
      93              : 
      94              : };
      95              : 
      96              : /// Instantiaion of xtChannels for the 16-channel xt1121
      97              : typedef xtChannels<16> xt1121Channels;
      98              : 
      99              : template<int numChannels>
     100            6 : xtChannels<numChannels>::xtChannels()
     101              : {
     102          102 :    for(size_t i =0; i< numChannels; ++i)
     103              :    {
     104           96 :       m_channels[i] = false;
     105           96 :       m_inputOnly[i] = false;
     106              :    }
     107            6 : }
     108              : 
     109              : template<int numChannels>
     110           54 : int xtChannels<numChannels>::setChannel( size_t chNo )
     111              : {
     112           54 :    if(chNo > numChannels - 1) return -1;
     113              : 
     114           54 :    if(m_inputOnly[chNo])
     115              :    {
     116            9 :       m_channels[chNo] = false;
     117            9 :       return 0;
     118              :    }
     119              : 
     120           45 :    m_channels[chNo] = true;
     121              : 
     122           45 :    return 0;
     123              : }
     124              : 
     125              : template<int numChannels>
     126            8 : int xtChannels<numChannels>::setInputOnly( size_t chNo )
     127              : {
     128            8 :    if(chNo > numChannels - 1) return -1;
     129              : 
     130            8 :    m_inputOnly[chNo] = true;
     131              : 
     132            8 :    return 0;
     133              : }
     134              : 
     135              : template<int numChannels>
     136            0 : int xtChannels<numChannels>::clearChannel( size_t chNo )
     137              : {
     138            0 :    if(chNo > numChannels - 1) return -1;
     139              : 
     140            0 :    m_channels[chNo] = false;
     141              : 
     142            0 :    return 0;
     143              : }
     144              : 
     145              : template<int numChannels>
     146           42 : int xtChannels<numChannels>::clearAll()
     147              : {
     148          714 :    for(size_t i=0;i<numChannels; ++i) m_channels[i] = false;
     149              : 
     150           42 :    return 0;
     151              : }
     152              : 
     153              : template<int numChannels>
     154           42 : int xtChannels<numChannels>::setRegisters( uint16_t registers[numRegisters] )
     155              : {
     156          210 :    for(size_t i =0; i < numRegisters; ++i)
     157              :    {
     158          168 :       registers[i] = 0;
     159              : 
     160          840 :       for(size_t j=0; j < 4; ++j)
     161              :       {
     162          672 :          if(!m_inputOnly[i*4 + j])
     163              :          {
     164              :             //Set the appropriate bit for this channel if it's true.
     165          588 :             if(m_channels[i*4+j])
     166              :             {
     167           45 :                registers[i] += (1 << j);
     168              :             }
     169              :          }
     170              :       }
     171              :    }
     172              : 
     173              : 
     174           42 :    return 0;
     175              : }
     176              : 
     177              : template<int numChannels>
     178           24 : int xtChannels<numChannels>::readRegisters( uint16_t registers[numRegisters] )
     179              : {
     180          120 :    for(size_t i =0; i < numRegisters; ++i)
     181              :    {
     182           96 :       m_channels[i*4] = ((registers[i] & 1) > 0);
     183           96 :       m_channels[i*4+1] = ((registers[i] & 2) > 0) ;
     184           96 :       m_channels[i*4+2] = ((registers[i] & 4) > 0);
     185           96 :       m_channels[i*4+3] = ((registers[i] & 8) > 0);
     186              :    }
     187              : 
     188              : 
     189           24 :    return 0;
     190              : }
     191              : 
     192              : template<int numChannels>
     193          384 : int xtChannels<numChannels>::channel( size_t chNo )
     194              : {
     195          384 :    if(chNo > numChannels - 1) return -1;
     196              : 
     197          384 :    return m_channels[chNo];
     198              : 
     199              : }
     200              : 
     201              : #endif //xtChannels_hpp
     202              : 
        

Generated by: LCOV version 2.0-1