Can’t you reverse the same 16 bits again to look at the correct value?
Can’t you reverse the same 16 bits again to look at the correct value?
I see.. you don’t know if it’s reversed because you aren’t tracking if it’s been reversed or not.
It would only take one more bit as a flag for if reversed or not, but I would copy to useless variable to send.
Code:useless var word ‘ don’t use for anything other than sending IF Voltage = 0 THEN GOTO MAIN ENDIF Voltage = (Voltage - 1) useless = Voltage REV 16 GOSUB SEND_useless 'pause 50 GOTO MAIN
I have an o'scope on the fiber transmitter and say I want the fiber signal to look like this (in ones and zeros, the fiber signal is actually two different widths to represent 1 or 0):
000000000000000101010000 - that is 24 bits, the last eight to the right are OK because they are the 8 from the MCP23S17 that is just static setup data and I can handle those... and they are on the proper side of the string and in the proper order. so no problem with those. BUT....
The first 16 bits are: 0000000000000001 - Decimal "1"
Well, if I use my code to send those 16 bits - the fiber output ends up looking more like this: 100000000000000001010000 - The first 16 bits are opposite of what I need! They equal decimal "32768"
Far from the "1" I was expecting!
It's actually worse than that, because the MCP23S17 is not acting like a 16 bit device, but rather as two 8 bit devices... hence the splitting of "Voltage" into two bytes. But I think I just need to configure the MCP23S17 correctly for 16 bit mode, as soon as I wrap my brain around its datasheet.
But I still need to know how to send just the 16 bit WORD "Voltage" in my code LSB first, without having to do crazy math every time I work with the variable in my MAIN loop
I tried the operator "REV" and it doesn't seem to work as expected.
I think the MCP23S17 must have it's data fed to it MSB first, but my variable has to go LSB first!
I wonder if I could just get away with this?:
Code:nCSA = 0 'Enable MCP23S17-A SHIFTOUT SDO, SCLK, 1, [MCP23A,OLATA] ' i.e. SHIFTOUT SDO, SCLK, MSB,[MCP23A,OLATA] SHIFTOUT SDO, SCLK, 0, [VoltageFst] ' i.e. SHIFTOUT SDO, SCLK, LSB,[VoltageFst] nCSA = 1 'Disable the MCP23S17 pause 1 nCSA = 0 'Enable MCP23S17-A SHIFTOUT SDO, SCLK, 1, [MCP23A,OLATB] ' i.e. SHIFTOUT SDO, SCLK, MSB,[MCP23A,OLATB] SHIFTOUT SDO, SCLK, 0, [VoltageSec] ' i.e. SHIFTOUT SDO, SCLK, LSB,[VoltageSec] nCSA = 1 'Disable the MCP23S17 RETURN
Using two bytes (PBP alias) I don’t think costs you any time even behind the scenes,
and then just addressing them in the order you want would be the next best thing to swapping the hardware.
I’m not familiar with the device, but if REV didn’t work as you expected, it sound like swapping bytes was the solution?
If that’s wrong, and it’s back to reversing bits, there’s no math to do it,
it’s always whacky procedural code emulating what a Human would do.
You can use the above method first (almost free), and then logical operators,
but it’s essentially the same goal as moving a ball around a table with paper cups.
I’ve got to do it this weekend, and don’t get to use REV, so this is what I came up with (untested).
There’s another thread about REV somewhere.. it was decompiled to find out instruction time,
and I don’t know right now If I’m beating it.
Code:sixteenbit var word revsixteen var word leasteight var sixteenbit.byte0 mosteight var sixteenbit.byte1 leastrev var revsixteen.byte0 mostrev var revsixteen.byte1 count var byte reversesixteen: for count = 0 to 7 leastrev.bit7 = mosteight.bit0 mosteight << 1 leastrev >> 1 mostrev.bit7 = leasteight.bit0 leasteight << 1 mostrev >> 1 next count return
The following snippit displays what I would expect.I tried the operator "REV" and it doesn't seem to work as expected.
DisplayCode:myWord var word myTest var word Low PORTE.2 ' LCD R/W low = write Pause 10 ' Wait for LCD to startup main: lcdout $fe, 1 pause 1000 myWord = $1 myTest = myWord rev 16 lcdout $fe, $80, ihex4 myWord, ":",ihex4 myTest," ","W:T" 'Store reversed value in separate var myWord = $8000 myTest = myWord rev 16 lcdout $fe, $c0, ihex4 myWord,":",ihex4 myTest," ","W:T" 'Store reversed value in separate var pause 1000 lcdout $fe, 1 myWord = $1 lcdout $fe, $80, ihex4 myWord, ":" myWord = myWord rev 16 lcdout $fe, $80+6, ihex4 myWord, " ", "W:W" 'Store reversed value in same var pause 1000 myWord = $8000 lcdout $fe, $c0, ihex4 myWord, ":" myWord = myWord rev 16 lcdout $fe, $c0+6, ihex4 myWord, " ", "W:W" 'Store reversed value in same var pause 1000 goto main
Also, I think you are right in that you should be able to use the " SHIFTOUT SDO, SCLK, 0, [VoltageFst]"
Regards,
TABSoft
Here's a few tips
First off, don't REV anything. That's only going to confuse the issue.
The MCP23S17 expects the bytes to be sent MSB first, that is the first bit clocked out appears at GPx7 and the last bit appears at GPx0.
That's what you should get if you specify MSBFIRST in the SHIFTOUT instruction
If you need to reverse the bits at the output port, then specify LSBFIRST in the SHIFTOUT instructionCode:SHIFTOUT SDO, SCLK, 1, [databyte]
Code:SHIFTOUT SDO, SCLK, 0, [databyte]
Now, on to the ordering of bytes. When you have a word declaration like
That would give you VoltageFst = $01, and VoltageSec = $80Code:Voltage VAR WORD VoltageFst VAR Voltage.BYTE0 'this is the lower byte of the word VoltageSec VAR Voltage.BYTE1 'this is the upper byte of the word Voltage = $8001
So, if you used your send routine with those values
You end up with:Code:nCSA = 0 'Enable MCP23S17-A SHIFTOUT SDO, SCLK, 1, [MCP23A,OLATA] ' i.e. SHIFTOUT SDO, SCLK, MSB,[MCP23A,OLATA] SHIFTOUT SDO, SCLK, 0, [VoltageFst] ' i.e. SHIFTOUT SDO, SCLK, LSB,[VoltageFst] nCSA = 1 'Disable the MCP23S17 pause 1 nCSA = 0 'Enable MCP23S17-A SHIFTOUT SDO, SCLK, 1, [MCP23A,OLATB] ' i.e. SHIFTOUT SDO, SCLK, MSB,[MCP23A,OLATB] SHIFTOUT SDO, SCLK, 0, [VoltageSec] ' i.e. SHIFTOUT SDO, SCLK, LSB,[VoltageSec] nCSA = 1 'Disable the MCP23S17 RETURN
OLATA7:OLATA0 = $80 ' VoltageFst is $01, but was sent out LSB first so it swapped order
OLATB7:OLATB0 = $01 ' VoltageSec is $80, but was sent out LSB first so it swapped order
If that's not what you need then you'll either have to send VoltageFst to OLATB/VoltageSec to OLATA to swap the bytes,
and/or use MSB in the SHIFTOUT instruction, but that depends on exactly how the output ports are connected to the fiber interface.
In your case I wouldn't bother with trying to using 16-bit mode with the MCP23S17, at least not right now. That'll change all of the
register mapping addresses and likely confuse things even more. 16-bit mode can be faster, but since you're using SHIFTOUT instead
of the hardware MSSP it's already slow.
Awesome stuff guys!
Yes, when I got in and tried the thought that I had of just clocking in the set up register stuff first:
It worked just like Tabsoft and Tumbleweed both surmised (or tested!) and yes, the byte order was wrong as well, so I just swapped the two alias bytes:Code:nCSA = 0 'Enable MCP23S17-A SHIFTOUT SDO, SCLK, 1, [MCP23A,OLATA] ' i.e. SHIFTOUT SDO, SCLK, MSB,[MCP23A,OLATA] SHIFTOUT SDO, SCLK, 0, [VoltageFst] ' i.e. SHIFTOUT SDO, SCLK, LSB,[VoltageFst] nCSA = 1 'Disable the MCP23S17
And that gave me the full picture!Code:nCSA = 0 'Enable MCP23S17-A SHIFTOUT SDO, SCLK, 1, [MCP23A,OLATA] SHIFTOUT SDO, SCLK, 0, [VoltageSec] nCSA = 1 'Disable the MCP23S17 pause 1 nCSA = 0 'Enable MCP23S17-A SHIFTOUT SDO, SCLK, 1, [MCP23A,OLATB] SHIFTOUT SDO, SCLK, 0, [VoltageFst] nCSA = 1 'Disable the MCP23S17
So yay for my tired little brain at least showing some spark of life there with my hunch! Sometimes it's just good to put stuff up here to get the right thought patterns going.
And thank all of you for helping to fill in the blanks! You guys rock!
Now to get to tackling all the other stuff this thing needs to do.
Like I posted above, the PIC is handling a setup byte and then a 16 bit value that ends up setting a 16 bit DAC at the other end of a fiber optic link. The card my circuit is talking to is an OEM ADC/DAC card that uses two pulse widths to represent a one or zero. The widths are tight and the entire pulse train is pretty narrow, so the PIC couldn't begin to help with that. So its a mess of shift registers and one-shot chips that do the critical timing, the PIC presents the full 24 bits to a string of parallel shift registers via the MCP23S17's and sends an enable pulse to transmit when everything is set.
I'm working on another card that does the RX side by turning the pulse widths back into parallel data, and then I'll read them with a MCP23S17 again. Just 16 bits on the return.
I'll likely end up redoing the board for the send side since it's got some "blue wires" going on, and the fact it requires some trickery in code to map everything just right. But at least I can do some more debugging with it now.
My major mistake was the fact that I breadboarded the digital logic circuitry to figure that all out and never bothered to do the PIC stuff on there as well!!!
I've learned my lesson!
Thanks again guys! You are a wealth of knowledge and way more help than anyone could hope for!![]()
Bookmarks