Stuart Posted February 9, 2017 Share Posted February 9, 2017 Vorticon, on 08 Feb 2017 - 11:38 PM, said:Another weird thing: changing the stop bit count in the control register has absolutely no effect on the communication, either emission or reception... Something really fishy is going on here. I'm not sure you'll see an effect anyway in your application. I think the number of stop bits is only relevant if you are transmitted at the max rate, with a start bit immediately following the specified number of stop bits, which effectively provide 'padding' between the characters. A stop bit is a '1', which is also the 'idle state' of the line when no character is being transmitted. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 9, 2017 Author Share Posted February 9, 2017 I'm not sure you'll see an effect anyway in your application. I think the number of stop bits is only relevant if you are transmitted at the max rate, with a start bit immediately following the specified number of stop bits, which effectively provide 'padding' between the characters. A stop bit is a '1', which is also the 'idle state' of the line when no character is being transmitted. I only seem to have an issue with reception, not transmission. I am getting data back appropriately, but I can't figure out why the msb is getting set (CRU 7). Nothing I have read so far demonstrates a condition where that bit is set continuously in the receive buffer. Changing the baud rate changes the combination of bits being set which remain constant for that specific baud rate. All that is happening is that a byte is showing up at the Rx line on the TI and it is being put into the reception register and that register is getting corrupted. The Xbees have been configured to 8N1 with no control protocol, so it should be a pure direct transmission Tx to Rx. I tried using TELCO to verify the reception of the byte, but it did not work because I think it is expecting some form of handshake to occur first. Tomorrow I'm going to hook up my logic analyzer to the Ti's Rx line and see what the heck is coming through... Also another test is to introduce a delay on the Arduino side prior to sending the response. Since we are using GPL here and not assembly, it is possible that things are just happening too fast. Quote Link to comment Share on other sites More sharing options...
Omega-TI Posted February 9, 2017 Share Posted February 9, 2017 I've not followed this from the beginning, but I have to ask, are you using an RS-232 in the P-Box... or are you attempting this with a NanoPEB? Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 9, 2017 Author Share Posted February 9, 2017 I've not followed this from the beginning, but I have to ask, are you using an RS-232 in the P-Box... or are you attempting this with a NanoPEB? I'm using an RS232 card with the HDX modification, although the HDX is currently inactivated via a switch. I already have a CF7+ device and I see no point in getting a NanoPEB as well... 1 Quote Link to comment Share on other sites More sharing options...
Omega-TI Posted February 9, 2017 Share Posted February 9, 2017 Okay, good to know, because Telco will not work with a NanoPEB no matter what you do, so yeah, currently there no point even, if you did not already have a CF7. If you have the interrupt switched back on like you said, I have no clue why it's not working. Let us know what it is when you figure it out, I'm sure I'm not the only one interested in why it's flaky. Quote Link to comment Share on other sites More sharing options...
Tursi Posted February 9, 2017 Share Posted February 9, 2017 All that is happening is that a byte is showing up at the Rx line on the TI and it is being put into the reception register and that register is getting corrupted. The Xbees have been configured to 8N1 with no control protocol, so it should be a pure direct transmission Tx to Rx. I tried using TELCO to verify the reception of the byte, but it did not work because I think it is expecting some form of handshake to occur first. Huh, that is weird. I don't remember ever doing anything weird to receive characters on the RS232 port (from assembly). It sounds like framing problems, but that should be handled in the hardware. Although it's worth noting that you should get character back on Telco, but unless you are using an 8-bit terminal emulation like ANSI, you won't see characters with the high bit set (I think, that one's been a while). Logic analyzer will at least help rule out the input signal, so it sounds like a good path if you don't have anything else handy that can generate a serial line, but also might be worth trying from the PC if you have a serial port on there? Quote Link to comment Share on other sites More sharing options...
Stuart Posted February 9, 2017 Share Posted February 9, 2017 Tomorrow I'm going to hook up my logic analyzer to the Ti's Rx line and see what the heck is coming through... Also another test is to introduce a delay on the Arduino side prior to sending the response. Since we are using GPL here and not assembly, it is possible that things are just happening too fast. Logic analyser seems to be a good way to go. Just to point out another useful feature of the 9902 - CRU bit 15 enables you to test the state of the RIN (Receive In) pin directly. So using assembly (for the necessary speed), you could test bit 15 and wait until it goes low (indicating the start of a start bit), wait half a serial bit period, then sample each of the serial bits directly. You could then see exactly what is coming down the line, rather than what the 9902 is loading into the receive register. You'd need to do a bit of experimentation with timing loops to get the right values for the Baud rate you're using. The TIBUG monitor uses this technique to autodetect the Baud rate of your terminal: you power on then press a key for a character where the MSB is a '1'. The code measures the width of the start bit in a timing loop, then looks up the loop count in a small lookup table that gives the transmit/receive rate register values to load for that Baud rate. 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 10, 2017 Author Share Posted February 10, 2017 Huh, that is weird. I don't remember ever doing anything weird to receive characters on the RS232 port (from assembly). It sounds like framing problems, but that should be handled in the hardware. Although it's worth noting that you should get character back on Telco, but unless you are using an 8-bit terminal emulation like ANSI, you won't see characters with the high bit set (I think, that one's been a while). Logic analyzer will at least help rule out the input signal, so it sounds like a good path if you don't have anything else handy that can generate a serial line, but also might be worth trying from the PC if you have a serial port on there? The numbers I'm sending from the Arduino do not correspond to ASCII characters. I'm going to modify the Arduino code and have it send characters instead. And yes, I will try and use a PC terminal to test as well, but it's more fun to use a logic analyzer! Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 10, 2017 Author Share Posted February 10, 2017 Logic analyser seems to be a good way to go. Just to point out another useful feature of the 9902 - CRU bit 15 enables you to test the state of the RIN (Receive In) pin directly. So using assembly (for the necessary speed), you could test bit 15 and wait until it goes low (indicating the start of a start bit), wait half a serial bit period, then sample each of the serial bits directly. You could then see exactly what is coming down the line, rather than what the 9902 is loading into the receive register. You'd need to do a bit of experimentation with timing loops to get the right values for the Baud rate you're using. The TIBUG monitor uses this technique to autodetect the Baud rate of your terminal: you power on then press a key for a character where the MSB is a '1'. The code measures the width of the start bit in a timing loop, then looks up the loop count in a small lookup table that gives the transmit/receive rate register values to load for that Baud rate. This would be my last ditch effort if all else fails, but definitely something to consider. I did add a transmission delay on the Arduino side (1sec), and it made no difference, so it looks like RXB is able to keep up. 1 Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted February 10, 2017 Share Posted February 10, 2017 A few troubleshooting options : Have you tried connecting the Arduino to a PC / other device with terminal emulation? Have you tried connecting a PC to the TI, to rule out the Arduino? Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 11, 2017 Author Share Posted February 11, 2017 Well, here is the result of my testing so far, and unfortunately I am still no closer to solving this issue... I attached my logic analyzer to the XBees, and checked the binary stream on both ends. To recap, when I send an A from the TI, the Arduino responds with 255 and sends it via the XBee back to the TI. B sends a 1 and C sends a 0. In the images below, each division represents one bit of data sent in time. A sent. The response is essentially just the start bit since 255 is binary 11111111. B sent. Here we get the start bit, a one, then all zeros. C sent. Here we have the start bit and all zeros. So clearly the Arduino is sending the right data and XBees are faithfully transmitting that data. So next I hooked up the set up to my laptop via a serial to USB adapter and used HTERM to view the binary stream. A simple terminal program will not work as it can only display ASCII characters. Here again it looks like the PC is receiving the data appropriately with 255, 1 and 0 received. Basically then this leaves the issue squarely with the TI. Why am I getting corruption of the receive register? The only difference between the physical setup of the TI and PC is the use of a null modem adapter on the TI side. Any thoughts? Quote Link to comment Share on other sites More sharing options...
Stuart Posted February 11, 2017 Share Posted February 11, 2017 (edited) Vorticon, on 11 Feb 2017 - 8:29 PM, said:Vorticon, on 11 Feb 2017 - 8:29 PM, said: Any thoughts? Have you only tried it with RXB so far? I'd try it in assembly - you could adapt the code I posted earlier (just send a 'fixed' character and see what comes back). May be a bug in RXB, or you haven't got the CALL IO parameters quite right. *** BUT FIRST! *** In your code, add a new line 55 to set CRU bit 13 to zero. See what happens ... Edited February 11, 2017 by Stuart 3 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 12, 2017 Author Share Posted February 12, 2017 Have you only tried it with RXB so far? I'd try it in assembly - you could adapt the code I posted earlier (just send a 'fixed' character and see what comes back). May be a bug in RXB, or you haven't got the CALL IO parameters quite right. *** BUT FIRST! *** In your code, add a new line 55 to set CRU bit 13 to zero. See what happens ... Well I'll be damned! It worked! But how??? CRU bit 13 is supposed to be an input only bit indicating the arrival of the first bit of data, at least per Thierry's site. What exactly am I doing when I write to it? Heck it never even occurred to me that I could even do that... 2 Quote Link to comment Share on other sites More sharing options...
Stuart Posted February 12, 2017 Share Posted February 12, 2017 You'll have to wait until tomorrow for that as it requires a little explanation. It's late, and a warm bed awaits me. It will also give me a chance to ponder why you had trouble receiving, as it now looks like you should have had trouble transmitting, Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 12, 2017 Author Share Posted February 12, 2017 You'll have to wait until tomorrow for that as it requires a little explanation. It's late, and a warm bed awaits me. It will also give me a chance to ponder why you had trouble receiving, as it now looks like you should have had trouble transmitting, Will do Yeah transmission never seemed to be an issue... Now I know why I stick with the parallel port any chance I get! 1 Quote Link to comment Share on other sites More sharing options...
Opry99er Posted February 12, 2017 Share Posted February 12, 2017 Ha! 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted February 12, 2017 Share Posted February 12, 2017 This would be my last ditch effort if all else fails, but definitely something to consider. I did add a transmission delay on the Arduino side (1sec), and it made no difference, so it looks like RXB is able to keep up. LOL this had me worried I might have to fix this issue! Quote Link to comment Share on other sites More sharing options...
RXB Posted February 12, 2017 Share Posted February 12, 2017 Doing a soft reset on with CRU 31 and making RTS low with CRU 16 did the trick! It works now perfectly! Thanks Stuart! Here's the updated test code: 10 CALL CLEAR 20 CRU=2464 !CRU ADDRESS OF THE FIRST TMS9902 CHIP DIVIDED BY 2 30 CALL IO(3,1,2432,1) !ACTIVATE THE RS232 CARD 35 CALL IO(3,1,CRU+31,1) !RESET TMS9902 40 CALL IO(3,1,CRU+14,1) !SELECT CONTROL REGISTER 50 CALL IO(3,8,CRU,203) !8N1 @ 3MHZ 60 CALL IO(3,1,CRU+12,1) !SELECT RECEPTION RATE REGISTER 70 CALL IO(3,11,CRU,0,39) !9600 BPS 80 CALL IO(3,1,CRU+11,1) !SELECT EMISSION RATE REGISTER 90 CALL IO(3,11,CRU,0,39) !9600 BPS 100 FOR I=11 TO 14::CALL IO(3,1,CRU+I,0)::NEXT I !ENABLE EMIT REGISTER 110 PRINT "READY FOR INPUT" 120 CALL KEY(0,K,S)::IF S=0 THEN 120 !WAIT FOR KEYPRESS 130 PRINT K::CALL IO(3,8,CRU,K) !LOAD EMIT REGISTER 135 CALL IO(3,1,CRU+16,1) !SEND BYTE TO SERIAL PORT 140 GOTO 120 Not to be picky but you could change line 120 to: 120 CALL KEY("",0,K,S) ! WAIT FOR KEYPRESS RXB has a built in: IF K="VALUE" THEN NEXT ELSE LOOP Example: CALL KEY("X",0,K,S) ! Will loop forever till the X key is pressed CALL KEY("",0,K,S) ! Will loop forever til any key is pressed 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 12, 2017 Author Share Posted February 12, 2017 Not to be picky but you could change line 120 to: 120 CALL KEY("",0,K,S) ! WAIT FOR KEYPRESS RXB has a built in: IF K="VALUE" THEN NEXT ELSE LOOP Example: CALL KEY("X",0,K,S) ! Will loop forever till the X key is pressed CALL KEY("",0,K,S) ! Will loop forever til any key is pressed Oh nice! Good to know. Thanks for pointing that out. 1 Quote Link to comment Share on other sites More sharing options...
Stuart Posted February 12, 2017 Share Posted February 12, 2017 (edited) Vorticon, on 12 Feb 2017 - 12:20 AM, said:Vorticon, on 12 Feb 2017 - 12:20 AM, said:Vorticon, on 12 Feb 2017 - 12:20 AM, said: Well I'll be damned! It worked! But how??? CRU bit 13 is supposed to be an input only bit indicating the arrival of the first bit of data, at least per Thierry's site. What exactly am I doing when I write to it? Heck it never even occurred to me that I could even do that... So here's what I think is happening. There are a couple of points that I don't fully understand, but you seem to have a working solution. Also, you're better off looking at the TI data manual for this (ftp://ftp.whtech.com/datasheets%20and%20manuals/Datasheets%20-%20TI/TMS9902A.pdf) - it has tables covering all the input and output CRU bits, and Thierry's site doesn't cover everything. I'll refer to your code listing back in post #24. There are a number of registers available for programming: (1) Control Register - you select this for loading by writing a 1 to CRU bit 14. (2) Interval Register - selected for loading by writing a 1 to CRU bit 13. (3) Receive Data Rate Register - selected for loading by writing a 1 to CRU bit 12. (4) Transmit Data Rate Register - selected for loading by writing a 1 to CRU bit 11. You quite correctly selected and loaded registers 1, 3 and 4 in your code, lines 40 - 90. You load the register by writing one or more bits to CRU bits 10 - 0. We then added a soft reset of the 9902 in line 35. One effect of this is that it sets CRU bits 14 - 11 all to 1 - it selects *all* the registers for loading. So what happens in this condition? When you write to CRU bits 10 - 0, it writes to the first register that is selected using the priority order listed above. So with all the registers selected, the first write will be to the Control Register (which then deselects itself), the next write to the Interval Register, then the Receive Data Rate Register, then the Transmit Data Rate Register. So going through your code: -- Line 40 I don't think is necessary - CRU bit 14 is already set to 1 by the soft reset. Should be able to delete this line. -- Line 50 is good - it writes to the Control Register, which also clears CRU bit 14. -- Line 60 is not necessary - CRU bit 12 is already set to 1 by the soft reset. -- Line 70 is interesting - you intended to write to the Receive Data Rate Register, but the highest priority register currently selected (according to the list above) is the Interval Register, so this write goes to that register, which also clears CRU bit 13. (Writing to that register might start the interval timer which generates regular interrupts from the 9902, but I don't think that is a problem in this case.) -- Line 80 is not necessary - CRU bit 11 is already set to 1 by the soft reset. -- Line 90 - you intended to write to the Transmit Data Rate Register, but the highest priority register currently selected (according to the list above) is the Receive Data Rate Register. In the scenario we have at the moment, *both* the Receive and Transmit Data Rate Registers are selected, and in this case this write goes to *both* those registers (programming both with the same Baud rate). This also clears CRU bit 12. -- Line 100 - you're now clearing CRU bits 11 to 14. Bits 14, 13 and 12 are cleared already by writing to the registers, so it shouldn't be necessary to clear those. CRU bit 11 is still set, but the technique normally used to clear this is to write 12 bits in line 90 rather than 11 bits - the extra bit is written to bit 11 which clears it. The new line 55 I suggested to clear CRU bit 13 is deselecting the Interval Register so that the next write doesn't go to it. So your line 70 will write to *both* the Receive and Transmit Data Rate Registers, and your line 90 will write to the Transmit Data Rate Register alone (which is not necessary, but shouldn't cause a problem). Now, I'm not sure exactly why you were having a problem receiving when both the transmit *and* receive registers were being programmed. I may have to experiment a little. I think you should be able to revise your code as below to follow the 'normal' flow for programming the 9902: ... 35 CALL IO(3,1,CRU+31,1) !RESET TMS9902 40 (delete line) 50 CALL IO(3,8,CRU,203) !8N1 @ 3MHZ !PROGRAM CONTROL REGISTER 55 CALL IO(3,1,CRU+13,0) !DESELECT INTERVAL REGISTER 60 (delete line) 70 CALL IO(3,12,CRU,0,39) !9600 BPS !PROGRAM RECEIVE AND TRANSMIT DATA RATE REGISTERS ** Note the line above sends 12 bits, not 11 ** 80 (delete line) 90 (delete line) 100 (delete line) 110 PRINT "READY FOR INPUT" ... ... Edited February 12, 2017 by Stuart 2 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 12, 2017 Author Share Posted February 12, 2017 Thanks for the explanation Stuart! I did try out your code suggestion and its works great except that I still had to zero out CRU 11 prior to loading the emit buffer, so I suspect that CRU 11 is not being reset when using a single CALL IO for both the emit and receive rate registers. Also clearing CRU 18 after each reception byte was important otherwise I got overflow errors. So essentially the issue boiled down to having the interval timer accidentally set and running. Why this would corrupt the reception buffer remains unclear to me... In any case, I would grab a cigar but it's too darn cold outside still... I'll save it for Spring 2 Quote Link to comment Share on other sites More sharing options...
Stuart Posted February 12, 2017 Share Posted February 12, 2017 Clearing bit 18 after each received byte - yep, got to do that, as per post #13. The CALL IO line to load the transmit and receive rate registers - you modified the line to send 12 bits, not 11, to clear bit 11? (I tried configuring a serial port on my TM990 using assembly, using the configuration you were using, and it actually seemed to work OK. Whether it is the interval timer causing the problem or not, no idea. Glad it's up and running now though.) 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 12, 2017 Author Share Posted February 12, 2017 Clearing bit 18 after each received byte - yep, got to do that, as per post #13. The CALL IO line to load the transmit and receive rate registers - you modified the line to send 12 bits, not 11, to clear bit 11? (I tried configuring a serial port on my TM990 using assembly, using the configuration you were using, and it actually seemed to work OK. Whether it is the interval timer causing the problem or not, no idea. Glad it's up and running now though.) Ah no forgot to send 12 bits... In any case, thanks yet again for your help! I was really stuck here... I can just imagine how much more difficult it would have been to get timely help back in the day without the internet... 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.