LCOV - code coverage report
Current view: top level - src/MIDI_Inputs/MCU - SevenSegmentDisplay.hpp (source / functions) Hit Total Coverage
Test: 19d2efc7037c2e176feca44750a12594c76f466f Lines: 31 42 73.8 %
Date: 2019-11-24 14:50:27 Functions: 8 12 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <MIDI_Inputs/MIDIInputElementCC.hpp>
       4             : #include <Print.h>
       5             : #include <string.h>
       6             : 
       7             : BEGIN_CS_NAMESPACE
       8             : 
       9             : namespace MCU {
      10             : 
      11             : template <uint8_t LENGTH>
      12          13 : class SevenSegmentDisplay : public MIDIInputElementCC, public Printable {
      13             :   public:
      14             :     /**
      15             :     * @brief     Constructor.
      16             :     * @todo      Documentation.
      17             :     */
      18          13 :     SevenSegmentDisplay(const MIDICNChannelAddress &address)
      19          26 :         : MIDIInputElementCC{address} {
      20          13 :         fillWithSpaces();
      21          13 :     }
      22             : 
      23          13 :     void fillWithSpaces() {
      24         143 :         for (char &c : text)
      25         130 :             c = ' ';
      26          13 :     }
      27             : 
      28           0 :     void reset() override {
      29             : #ifdef SEVENSEG_RESET
      30             :         fillWithSpaces();
      31             : #endif
      32           0 :     }
      33             : 
      34             :   private:
      35             :     /**
      36             :      * @brief   Update a character.
      37             :      */
      38          67 :     virtual bool updateImpl(const ChannelMessageMatcher &midimsg,
      39             :                             const MIDICNChannelAddress &target) override {
      40          67 :         uint8_t index = LENGTH - 1 - getRangeIndex(target);
      41             :         // MIDI msg: character data → bits 0-5
      42             :         // MIDI msg: decimal point → bit 6 set, no decimal point → bit 6 not set
      43             :         // text:   decimal point → bit 7 set, no decimal point → bit 7 not set
      44          67 :         uint8_t decimalPt = (midimsg.data2 & 0x40) << 1;
      45          67 :         uint8_t chardata = midimsg.data2 & 0x3F;
      46          67 :         uint8_t character = chardata >= 0x20 ? chardata : chardata + 0x40;
      47          67 :         character |= decimalPt;
      48          67 :         text[index] = character;
      49          67 :         return true;
      50             :     }
      51             : 
      52             :     /// Check if the address of the incoming MIDI message is within the range
      53             :     /// of addresses of this element.
      54          67 :     bool match(const MIDICNChannelAddress &target) const override {
      55          67 :         return MIDICNChannelAddress::matchAddressInRange(target, address,
      56             :                                                          LENGTH);
      57             :     }
      58             : 
      59             :     /// @todo
      60          67 :     uint8_t getRangeIndex(const MIDICNChannelAddress &target) const {
      61          67 :         return target.getAddress() - this->address.getAddress();
      62             :     }
      63             : 
      64             :   public:
      65             :     /**
      66             :      * @brief   Copy the ASCII text into the given buffer.
      67             :      *
      68             :      * @param[out] buffer
      69             :      *          The destination to write the text to.
      70             :      *          Will be null-terminated.
      71             :      *          Should have a size of at least `length`+1 bytes.
      72             :      * @param[in] offset
      73             :      *          The offset to start copying from (in the source text, the offset
      74             :      *          in the destination buffer is always zero).
      75             :      * @param[in] length
      76             :      *          The number of characters to copy.
      77             :      */
      78          30 :     void getText(char *buffer, uint8_t offset = 0,
      79             :                  uint8_t length = LENGTH) const {
      80          30 :         if (offset >= LENGTH)
      81           1 :             offset = LENGTH - 1;
      82          30 :         if (length > LENGTH - offset)
      83           4 :             length = LENGTH - offset;
      84         172 :         for (uint8_t i = 0; i < length; i++)
      85         142 :             buffer[i] = getCharacterAt(i + offset);
      86          30 :         buffer[length] = '\0';
      87          30 :     }
      88             : 
      89             :     /**
      90             :      * @brief   Get the character at the given index.
      91             :      * @todo    Documentation.
      92             :      */
      93         176 :     char getCharacterAt(uint8_t index) const { return text[index] & 0x7F; }
      94             : 
      95             :     /**
      96             :      * @brief   Copy the decimal points into the given buffer.
      97             :      *
      98             :      * @param[out] buffer
      99             :      *          The destination to write the decimal points to.
     100             :      *          Should have a size of at least `LENGTH` bytes.
     101             :      */
     102             :     void getDecimalPoints(bool *buffer) const {
     103             :         for (uint8_t i = 0; i < LENGTH; i++)
     104             :             buffer[i] = getDecimalPointAt(i);
     105             :     }
     106             : 
     107             :     /**
     108             :      * @brief   Get the decimal point state at the given index.
     109             :      * @todo    Documentation.
     110             :      */
     111           0 :     bool getDecimalPointAt(uint8_t index) const { return text[index] & 0x80; }
     112             : 
     113             :     /**
     114             :      * @brief   Print out the text of the display to the given Print.
     115             :      */
     116           0 :     size_t printTo(Print &printer) const override {
     117           0 :         size_t s = 0;
     118           0 :         for (uint8_t i = 0; i < LENGTH; i++) {
     119           0 :             s += printer.print(getCharacterAt(i));
     120           0 :             if (getDecimalPointAt(i))
     121           0 :                 s += printer.print('.');
     122           0 :         }
     123           0 :         return s;
     124             :     }
     125             : 
     126             :   private:
     127             :     char text[LENGTH];
     128             : };
     129             : 
     130             : } // namespace MCU
     131             : 
     132             : END_CS_NAMESPACE

Generated by: LCOV version 1.14-5-g4ff2ed6