Menu

Binary logic has me lost.

Help
mkstevo
2019-04-06
2019-04-08
  • mkstevo

    mkstevo - 2019-04-06

    Not for the first time, I'm lost in Binary land.

    I'm building a display translator that will decode data sent by another circuit to a seven segment (plus decimal point) four digit, LED display that is long since obsolete. The original displays are TSM6755 that have an SPI type interface with a clock and data line. The display driver has a similar protocol to the MM5450 type of device. It requires a fixed 36 clock cycles to be sent, the first clock cycle requires the data bit to be '1' to reset the device, the following 34 clock cycles clock the data into the displays, and the final clock cycle latches the data into the display segments. Hopefully I've explained that correctly.

    There are two types of 'transmitter' board types, with two types of displays, with the transmit boards sending the data with either 8uS, or 40uS clock/data pulse widths, with a gap between display refreshes of either 100mS or 200mS. Finally while the format of the display data has the same 36 clock cycles, the data sent is mapped to the display elements in a totally different way.

    So. My plan is to try to capture the data stream, ignoring bit 0, bit 35, also ignoring bits 33 and 34 as these control display elements that:
    a.) I don't have.
    b.) Are not used anyway.

    This leaves me with 32 bits of data, eight bits per display digit, four bytes required.

    Once I've got the data I plan to measure the clock pulse width to determine which type of display format is being sent, decode the stream apropriately and the send the decoded data to some displays of my own design which use 74HC595 serial latches to drive my LED displays. The decoder will hopefully determine the data protocol, decode it and I can use one display to replace two different obselete displays, automagically.

    This section of the 'capture' I seem to have got working, I got my test circuit knocked up yesterday, and was rather pleased to see that using the two different types of boards which send the data to the displays, at wildly differing speeds, with totally incompatible character maps, manages to capture the sent data streams apparently reliably. I'm sending this to a serial LCD display for a start so that I can check that my capture is working, is reliably measuring the clock pulse width and filling the four bytes of captured data correctly.

    What is leaving me baffled is the 'values' of the data I'm getting. The earliest type of display and board I've got when idle, sends " - - - - " to the display. Which, according to the datasheet for the TSM6755 is element 'G' [shown page 1, Figure 1, block diagram] this should equate to data element 4, 12, 20 and 28 [Page 4, Table 1, Serial Input Sequence]. This I'd expected to leave me with a decimal value of '8' in each of my captured data variables (imaginatively called Da1, Dat2, Dat3 and Dat4) but I'm getting a value of '32'.

    I'm thinking that it is probably related to how I'm loading the data into the byte by placing the current data element in Bit.0 and then rotating it left, leaving Bit.0 ready for the next data element. But, as I say, I'm not very good with binary logic and can't see the woods for the trees.

    Do
    
      Do 'Wait until any 'part' messages have finished
    
        If ClkIn = 1 Then
          Let ClkPause = 0
        End If
    
        Wait 1 uS
        Let ClkPause = ClkPause + 1
    
      Loop Until ClkPause > 1000 '1mS
    
      Capture
      SendCapture
    
    Loop
    
    Sub Capture
    
      Let Dat1 = 0
      Let Dat2 = 0
      Let Dat3 = 0
      Let Dat4 = 0
    
      Let ClkPause  = 0
      Let ClkCount  = 0
      Let TempWidth = 0
      Let ClkWidth  = 0
    
      Do
    
        If ClkIn = 1 Then
    
          If ClkCount > 0 Then
    
            If ClkCount < 9 Then
              Let Dat1.0 = DatIn
              Rotate Dat1 Left Simple
            End If
    
            If ClkCount < 17 Then
              If ClkCount > 8 Then
                Let Dat2.0 = DatIn
                Rotate Dat2 Left Simple
              End If
            End If
    
            If ClkCount < 25 Then
              If ClkCount > 16 Then
                Let Dat3.0 = DatIn
                Rotate Dat3 Left Simple
              End If
            End If
    
            If ClkCount < 33 Then
              If ClkCount > 24 Then
                Let Dat4.0 = DatIn
                Rotate Dat4 Left Simple
              End If
            End If
    
          End If
    
          Let ClkCount = ClkCount + 1
    
          Do
            Let TempWidth = TempWidth + 1
          Loop Until ClkIn = 0
    
          If TempWidth > ClkWidth Then
            Let ClkWidth = TempWidth 'Find the greatest time for the Clock pulse width
          End If
    
          Let TempWidth = 0
    
        End If
    
      Loop Until ClkCount = 36
    
    End Sub
    
     

    Last edit: mkstevo 2019-04-06
  • mkstevo

    mkstevo - 2019-04-06

    TSM6755 datasheet.

     
  • mkstevo

    mkstevo - 2019-04-06

    Thanks for the link.

    I'm really sorry but I can't see how, or where, or what, is collecting the data.

    I would guess it is the function:

    function GlcdReadData32 ( in reg ) as long
    

    But I just don't understand how it is working.

    Simple my code isn't! I can't deny that. Although capturing the width of the clock pulse is a vital part as it will tell me how to later decode the captured data.

    Having the wrong values in the captured data isn't a problem as I've later got to move them around in one of two ways (determined by the clock pulse width) anyway. I was confused by why I didn't get a value of '8' but instead got '32'. I must be rotating my bits in the wrong order, but can't see how or where.

    Having looked at this properly, it appears as though I need to load the seventh bit (Dat1.7) rotating right before placing the data into Dat1.7.

                128 64  32  16  8   4   2   1
    Data Bit
    Bit 0       0   0   0   0   0   0   0   0
    Rotate Left 0   0   0   0   0   0   0   0
    Bit 1       0   0   0   0   0   0   0   0
    Rotate Left 0   0   0   0   0   0   0   0
    Bit 2       0   0   0   0   0   0   0   0
    Rotate Left 0   0   0   0   0   0   0   0
    Bit 3       0   0   0   0   0   0   0   1
    Rotate Left 0   0   0   0   0   0   1   0
    Bit 4       0   0   0   0   0   0   1   0
    Rotate Left 0   0   0   0   0   1   0   0
    Bit 5       0   0   0   0   0   1   0   0
    Rotate Left 0   0   0   0   1   0   0   0
    Bit 6       0   0   0   0   1   0   0   0
    Rotate Left 0   0   0   1   0   0   0   0
    Bit 7       0   0   0   1   0   0   0   0
    Rotate Left 0   0   1   0   0   0   0   0
                128 64  32  16  8   4   2   1
    Rotate Rght 0   0   0   0   0   0   0   0
    Bit 0       0   0   0   0   0   0   0   0
    Rotate Rght 0   0   0   0   0   0   0   0
    Bit 1       0   0   0   0   0   0   0   0
    Rotate Rght 0   0   0   0   0   0   0   0
    Bit 2       0   0   0   0   0   0   0   0
    Rotate Rght 0   0   0   0   0   0   0   0
    Bit 3       1   0   0   0   0   0   0   0
    Rotate Rght 0   1   0   0   0   0   0   0
    Bit 4       0   1   0   0   0   0   0   0
    Rotate Rght 0   0   1   0   0   0   0   0
    Bit 5       0   0   1   0   0   0   0   0
    Rotate Rght 0   0   0   1   0   0   0   0
    Bit 6       0   0   0   1   0   0   0   0
    Rotate Rght 0   0   0   0   1   0   0   0
    Bit 7       0   0   0   0   1   0   0   0
                128 64  32  16  8   4   2   1
    

    So, assuming I've worked that out correctly, this should give me the '8' into my Dat1, Dat2, Dat3 and Dat4 values:

    Sub Capture
    
      Let Dat1 = 0
      Let Dat2 = 0
      Let Dat3 = 0
      Let Dat4 = 0
    
      Let ClkPause  = 0
      Let ClkCount  = 0
      Let TempWidth = 0
      Let ClkWidth  = 0
    
      Do
    
        If ClkIn = 1 Then
    
          If ClkCount > 0 Then
    
            If ClkCount < 9 Then
               Rotate Dat1 Right Simple
               Let Dat1.0 = DatIn
            End If
    
            If ClkCount < 17 Then
              If ClkCount > 8 Then
                Rotate Dat2 Right Simple
                Let Dat2.7 = DatIn
              End If
            End If
    
            If ClkCount < 25 Then
              If ClkCount > 16 Then
                Rotate Dat3 Right Simple
                Let Dat3.7 = DatIn
              End If
            End If
    
            If ClkCount < 33 Then
              If ClkCount > 24 Then
                Rotate Dat4 Right Simple
                Let Dat4.7 = DatIn
              End If
            End If
    
          End If
    
          Let ClkCount = ClkCount + 1
    
          Do
            Let TempWidth = TempWidth + 1
          Loop Until ClkIn = 0
    
          If TempWidth > ClkWidth Then
            Let ClkWidth = TempWidth 'Find the greatest time for the Clock pulse width
          End If
    
          Let TempWidth = 0
    
        End If
    
      Loop Until ClkCount = 36
    
    End Sub
    

    I can hardly wait to get back to work and try this out now.

     

    Last edit: mkstevo 2019-04-06
  • mkstevo

    mkstevo - 2019-04-08

    Having had time to look at this today, I found that making the adjustments I theorised about above did place the correct values into my 'captured' variables. For the display of " - - - - " on the four seven segment displays I now got '8' , '8' , '8' , '8' . Great.

    Knocking up a quick 'transmitter' to send individual values so that I could check the mapping of the bits within my captured bytes to the display elements, then revealed that the left most display segment values are not the first values received, but the last. Though the datasheet did allude to this, I had misunderstood. On the LED displays I designed, it seemed more logical to me to have the right most display the 'first' to make scrolling text much easier. As my displays are static, I can feed in a character on the right most side which moves any other 'text' one step to the left, a more natural scrolling direction.

    Having sorted all that out, I was able to take the captured data from the original (now obselete) display, translate it to 'my' display format and output this to the new display. Data being shown on both displays simultaneously.

    My final job is to create two output routines so that where the clock pulse width is less than 50 uS, translate from the display format for 'display A' and when greater than 50 uS translate from the format for 'display B'.

    Sub Capture
    
      Let Dat1 = 0
      Let Dat2 = 0
      Let Dat3 = 0
      Let Dat4 = 0
    
      Let ClkPause  = 0
      Let ClkCount  = 0
      Let TempWidth = 0
      Let ClkWidth  = 0
    
      Do
    
        If ClkIn = 1 Then
    
          If ClkCount > 0 Then
    
            If ClkCount < 9 Then
               Rotate Dat4 Right Simple
               Let Dat4.0 = DatIn
            End If
    
            If ClkCount < 17 Then
              If ClkCount > 8 Then
                Rotate Dat3 Right Simple
                Let Dat3.7 = DatIn
              End If
            End If
    
            If ClkCount < 25 Then
              If ClkCount > 16 Then
                Rotate Dat2 Right Simple
                Let Dat2.7 = DatIn
              End If
            End If
    
            If ClkCount < 33 Then
              If ClkCount > 24 Then
                Rotate Dat1 Right Simple
                Let Dat1.7 = DatIn
              End If
            End If
    
          End If
    
          Let ClkCount = ClkCount + 1
    
          Do
            Let TempWidth = TempWidth + 1
          Loop Until ClkIn = 0
    
          If TempWidth > ClkWidth Then
            Let ClkWidth = TempWidth 'Find the greatest time for the Clock pulse width
          End If
    
          Let TempWidth = 0
    
        End If
    
      Loop Until ClkCount = 36
    
    End Sub
    
     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.