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.
DoDo'Wait until any 'part' messages have finishedIfClkIn=1ThenLetClkPause=0EndIfWait1uSLetClkPause=ClkPause+1LoopUntilClkPause>1000'1mSCaptureSendCaptureLoopSubCaptureLetDat1=0LetDat2=0LetDat3=0LetDat4=0LetClkPause=0LetClkCount=0LetTempWidth=0LetClkWidth=0DoIfClkIn=1ThenIfClkCount>0ThenIfClkCount<9ThenLetDat1.0=DatInRotateDat1LeftSimpleEndIfIfClkCount<17ThenIfClkCount>8ThenLetDat2.0=DatInRotateDat2LeftSimpleEndIfEndIfIfClkCount<25ThenIfClkCount>16ThenLetDat3.0=DatInRotateDat3LeftSimpleEndIfEndIfIfClkCount<33ThenIfClkCount>24ThenLetDat4.0=DatInRotateDat4LeftSimpleEndIfEndIfEndIfLetClkCount=ClkCount+1DoLetTempWidth=TempWidth+1LoopUntilClkIn=0IfTempWidth>ClkWidthThenLetClkWidth=TempWidth'Find the greatest time for the Clock pulse widthEndIfLetTempWidth=0EndIfLoopUntilClkCount=36EndSub
Last edit: mkstevo 2019-04-06
If you would like to refer to this comment somewhere else in this project, copy and paste the following 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:
functionGlcdReadData32(inreg)aslong
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.
So, assuming I've worked that out correctly, this should give me the '8' into my Dat1, Dat2, Dat3 and Dat4 values:
SubCaptureLetDat1=0LetDat2=0LetDat3=0LetDat4=0LetClkPause=0LetClkCount=0LetTempWidth=0LetClkWidth=0DoIfClkIn=1ThenIfClkCount>0ThenIfClkCount<9ThenRotateDat1RightSimpleLetDat1.0=DatInEndIfIfClkCount<17ThenIfClkCount>8ThenRotateDat2RightSimpleLetDat2.7=DatInEndIfEndIfIfClkCount<25ThenIfClkCount>16ThenRotateDat3RightSimpleLetDat3.7=DatInEndIfEndIfIfClkCount<33ThenIfClkCount>24ThenRotateDat4RightSimpleLetDat4.7=DatInEndIfEndIfEndIfLetClkCount=ClkCount+1DoLetTempWidth=TempWidth+1LoopUntilClkIn=0IfTempWidth>ClkWidthThenLetClkWidth=TempWidth'Find the greatest time for the Clock pulse widthEndIfLetTempWidth=0EndIfLoopUntilClkCount=36EndSub
I can hardly wait to get back to work and try this out now.
Last edit: mkstevo 2019-04-06
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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'.
SubCaptureLetDat1=0LetDat2=0LetDat3=0LetDat4=0LetClkPause=0LetClkCount=0LetTempWidth=0LetClkWidth=0DoIfClkIn=1ThenIfClkCount>0ThenIfClkCount<9ThenRotateDat4RightSimpleLetDat4.0=DatInEndIfIfClkCount<17ThenIfClkCount>8ThenRotateDat3RightSimpleLetDat3.7=DatInEndIfEndIfIfClkCount<25ThenIfClkCount>16ThenRotateDat2RightSimpleLetDat2.7=DatInEndIfEndIfIfClkCount<33ThenIfClkCount>24ThenRotateDat1RightSimpleLetDat1.7=DatInEndIfEndIfEndIfLetClkCount=ClkCount+1DoLetTempWidth=TempWidth+1LoopUntilClkIn=0IfTempWidth>ClkWidthThenLetClkWidth=TempWidth'Find the greatest time for the Clock pulse widthEndIfLetTempWidth=0EndIfLoopUntilClkCount=36EndSub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
Last edit: mkstevo 2019-04-06
TSM6755 datasheet.
Have a look at https://github.com/Anobium/Great-Cow-BASIC-Demonstration-Sources/blob/master/GLCD_Solutions/GLCD_Discovery_for_MCUFRIEND_devices/GLCD_Discovery_SPI_Data.gcb
This shows you how to do a 32, 24, 16 and 8 SPI by bit banging. If you want a quick piece of code to simplify - let me know.
But, it is a lot easier than your code. :-)
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:
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.
So, assuming I've worked that out correctly, this should give me the '8' into my Dat1, Dat2, Dat3 and Dat4 values:
I can hardly wait to get back to work and try this out now.
Last edit: mkstevo 2019-04-06
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'.