+Vorticon Posted February 3, 2017 Share Posted February 3, 2017 So I've been trying to set the serial port using RXB as part of my experimentation with the wireless weather station project. Here's the test program, which waits for key input and sends a character to the serial port: 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 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) !SEND BYTE TO SERIAL PORT 140 GOTO 120 Well, it's not working. I know that my Xbee wireless setup is working because it functions normally when using TELCO at 9600bps 8N1, so I don't think it's a cabling issue. I am using a null modem cable here. Regarding lines 70 and 90, the RXB documentation states that when setting up more than 8bits, then 2 variables need to be used to create a 16bit number, and they need to be right justified. Here I need to send the first 11bits of >0027, i.e 0 and 39 decimal. However I am not clear if RXB uses the first number or the second as the LSB. I tried it both ways and it still did not work, but it's important to clarify that in any case. I can't seem to find anything wrong with my code, so if anyone here is familiar with serial communication on the TI I would immensely appreciate it if you could take a peek at it. Oh and BTW, I did test my console and it is running at 3MHZ, not 2.5MHZ... Quote Link to comment Share on other sites More sharing options...
Stuart Posted February 3, 2017 Share Posted February 3, 2017 Are you switching on CRU bit 16 to enable the transmitter (and I think you need /RTS connected to /CTS in your cable)? Take a look at section 4.2 of the TMS9902 data manual, if you haven't already. Might also be worth doing a soft reset of the 9902 (CRU bit 31) to get it into a known state as well. Bit of code below for initialising the RS-232 port in the NanoPEB. Should work for the RS-232 PEB card as well. *Set port to 1200 Baud, 7 data bits, no parity, 1 stop bit. LI R12,BA9902 CRU base address of 9902 in NanoPEB. SBO 31 Reset 9902. LI R1,>8200 Control register: 1 stop bit, no parity, 7 data * bits (binary 10000010). LDCR R1,8 Load control register. SBZ 13 Disable loading of interval register. LI R1,>01A0 1200 Baud. LDCR R1,12 Load transmit and receive data rate registers. SBO 16 Set /RTS active low. Quote Link to comment Share on other sites More sharing options...
RXB Posted February 3, 2017 Share Posted February 3, 2017 Wow this is just so freaking cool! In RXB I use the same exact code used in GPL for the TE2 Module that is also written in GPL so it may be a cable problem or a problem with the RS232 Card in how it works with GPL. In my GPL code I CLRFAC (clear 8 bytes of FAC) >834A and fetch first variable put it in VAR0 (>8300) then fetch second variable and put it in VARV (>8301) then CALL IO to send the byte to CRU address previously loaded. So variable one 0 is msb and variable two 39 is lsb. Or 00000000:00100111 in Binary. Isn't there a Address you are supposed to send bytes to on the RS232 card at >5000 seems like someone has mentioned this before? I thought line 130 should be: 130 PRINT K :: CALL LOAD(20480,K) ! SEND BYTE TO THE SERIAL BUFFER Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 3, 2017 Author Share Posted February 3, 2017 Are you switching on CRU bit 16 to enable the transmitter (and I think you need /RTS connected to /CTS in your cable)? Take a look at section 4.2 of the TMS9902 data manual, if you haven't already. Might also be worth doing a soft reset of the 9902 (CRU bit 31) to get it into a known state as well. Bit of code below for initialising the RS-232 port in the NanoPEB. Should work for the RS-232 PEB card as well. *Set port to 1200 Baud, 7 data bits, no parity, 1 stop bit. LI R12,BA9902 CRU base address of 9902 in NanoPEB. SBO 31 Reset 9902. LI R1,>8200 Control register: 1 stop bit, no parity, 7 data * bits (binary 10000010). LDCR R1,8 Load control register. SBZ 13 Disable loading of interval register. LI R1,>01A0 1200 Baud. LDCR R1,12 Load transmit and receive data rate registers. SBO 16 Set /RTS active low. My only reference has been Thierry Nouspikel's site and there is no mention there of switching on CRU 16 before transmission specifically, although it is listed as making RTS low. In retrospect, that makes sense... I'll give it a try! The XBee uses only 2 lines, the Tx and Rx, and it worked fine with TELCO using a standard null modem cable. I'll keep you posted. Thanks! 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 3, 2017 Author Share Posted February 3, 2017 Wow this is just so freaking cool! In RXB I use the same exact code used in GPL for the TE2 Module that is also written in GPL so it may be a cable problem or a problem with the RS232 Card in how it works with GPL. In my GPL code I CLRFAC (clear 8 bytes of FAC) >834A and fetch first variable put it in VAR0 (>8300) then fetch second variable and put it in VARV (>8301) then CALL IO to send the byte to CRU address previously loaded. So variable one 0 is msb and variable two 39 is lsb. Or 00000000:00100111 in Binary. Isn't there a Address you are supposed to send bytes to on the RS232 card at >5000 seems like someone has mentioned this before? I thought line 130 should be: 130 PRINT K :: CALL LOAD(20480,K) ! SEND BYTE TO THE SERIAL BUFFER Thanks for the clarification Rich. Address >5000 is for the parallel port only. 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 3, 2017 Author Share Posted February 3, 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 3 Quote Link to comment Share on other sites More sharing options...
Stuart Posted February 3, 2017 Share Posted February 3, 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! You could probably clarify the flow slightly in your revised code. If you take line 135 and move to a new line 105, and change the comment to "Set /RTS active". With the 9902 in that condition, then your line 130 will send the character immediately. You only need to set /RTS active once - it will stay in that condition until you manually set it inactive. It doesn't reset automatically after each character you send. Good work, and nice to see something being done in RXB. 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted February 3, 2017 Share Posted February 3, 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 Cool I will include this in next RXB manual as an example in CALL IO! 3 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 3, 2017 Author Share Posted February 3, 2017 You could probably clarify the flow slightly in your revised code. If you take line 135 and move to a new line 105, and change the comment to "Set /RTS active". With the 9902 in that condition, then your line 130 will send the character immediately. You only need to set /RTS active once - it will stay in that condition until you manually set it inactive. It doesn't reset automatically after each character you send. Good work, and nice to see something being done in RXB. Good to know. Thanks again. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 3, 2017 Author Share Posted February 3, 2017 Cool I will include this in next RXB manual as an example in CALL IO! CALL IO opened up a lot of interfacing possibilities for me with RXB I think the main limitation is going to be the relative sluggishness of GPL compared to straight assembly. That's not likely to be an issue with the wireless weather station project since an update every few seconds will be more than enough, but it might be a problem with more timing sensitive applications. Quote Link to comment Share on other sites More sharing options...
RXB Posted February 4, 2017 Share Posted February 4, 2017 The advantage of XB over Assembly is time to develop and modify programs, also Debugging is 1000 times faster. Complied languages area black hole time sink, I know I write GPL and speed in rewrite, compile and then test again is brutal! I have also done this with Assembly and same issue, it is not quick or easy to do. XB has the clear advantage of write/test rewrite/test with very little time needed to debug. (Also XB gives you ERROR CODES that help debugging, unlike Assembly or GPL or any compiled language.) Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 5, 2017 Author Share Posted February 5, 2017 One thing I can't seem to glean from Thierry's site is how to set up for receiving a byte. I know that CRU bits 0 to 7 are used for the reception register, but what conditions need to be set (i.e. what other CRU bits need to be changed) in order to enable reception since the same 0-7 bits are also used for the emit register? Quote Link to comment Share on other sites More sharing options...
Stuart Posted February 5, 2017 Share Posted February 5, 2017 (edited) Vorticon, on 05 Feb 2017 - 01:00 AM, said:Vorticon, on 05 Feb 2017 - 01:00 AM, said:One thing I can't seem to glean from Thierry's site is how to set up for receiving a byte. I know that CRU bits 0 to 7 are used for the reception register, but what conditions need to be set (i.e. what other CRU bits need to be changed) in order to enable reception since the same 0-7 bits are also used for the emit register? You don't need to change anything to receive. You just need to check if a character has been received into the receive buffer register, and if it has, read the character and reset the register. The CRU bits have different functions depending on whether you're reading or writing, so no problem using the same CRU bits to both transmit and receive a character. Some example code below. CLR R1 WAIT3 TB 21 Receive buffer register full? JNE WAIT3 No, loop until a character is received. STCR R1,8 Read character into MSB of R1. SBZ 18 Reset receive buffer register. Edited February 5, 2017 by Stuart 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 5, 2017 Author Share Posted February 5, 2017 Thanks again Stuart. That worked. However, I ran into a perplexing issue: I have the remote Arduino send a single byte 0,1 or 255 in response to a command from the TI using the Serial.write() command from the Serial Arduino library. What I am receiving on the TI end is the correct byte but with the MSB set to 1. In other words, when the Arduino sends a 0, I get 128, with a 1 I get 129, but with 255 I get predictably 255. I don't thing it's an issue with the Arduino, so I'm suspecting RXB here. The command to read the byte is CALL IO (2,8,CRU,DATAIN). I wonder if Rich can weigh in on this... When I have time tonight or tomorrow, I'll write a short test assembly program to verify that the received byte is correct from the Arduino side. Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted February 6, 2017 Share Posted February 6, 2017 Low level IO in RXB is pretty powerful, given the TI OS requires CRU access, and regular XB doesn't provide access outside the DSR mechanism... but I'm curious why you need it... Can you not OPEN #_ ... "RS232/1.param=val.param=val.param=val" or whatever the syntax was, and use the DSR from any XB, or TI BASIC? http://www.digitpress.com/library/manuals/ti994a/rs232%20interface%20card.pdf I know the DSR doesn't let you go very fast... but neither will any form of basic. -M@ Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 6, 2017 Author Share Posted February 6, 2017 Low level IO in RXB is pretty powerful, given the TI OS requires CRU access, and regular XB doesn't provide access outside the DSR mechanism... but I'm curious why you need it... Can you not OPEN #_ ... "RS232/1.param=val.param=val.param=val" or whatever the syntax was, and use the DSR from any XB, or TI BASIC? http://www.digitpress.com/library/manuals/ti994a/rs232%20interface%20card.pdf I know the DSR doesn't let you go very fast... but neither will any form of basic. -M@ I tried that and while I am able to send character data to the XBee, I have not been able to successfully receive data back as I kept getting I/O ERROR 26 (device not connected). I think that process requires the DTR/CTS lines to be connected, something the XBee does not have. Using CALL IO on the other hand allows for extreme flexibility in how the serial transmission is happening, and is likely faster as well... 2 Quote Link to comment Share on other sites More sharing options...
RXB Posted February 6, 2017 Share Posted February 6, 2017 Low level IO in RXB is pretty powerful, given the TI OS requires CRU access, and regular XB doesn't provide access outside the DSR mechanism... but I'm curious why you need it... Can you not OPEN #_ ... "RS232/1.param=val.param=val.param=val" or whatever the syntax was, and use the DSR from any XB, or TI BASIC? http://www.digitpress.com/library/manuals/ti994a/rs232%20interface%20card.pdf I know the DSR doesn't let you go very fast... but neither will any form of basic. -M@ Ok first off RXB is EXTENDED BASIC not slooow BASIC like in the console. Secondly RXB uses IO to access the IO chip 9902 in the Console directly using GPL which means you can do this without Assembly or a 32K needed, just RXB and a console. Third how would you open a port like say DATA IN using Basic like OPEN? (RXB can do this with CALL IO using CRU chip access) Now as RXB is Extended Basic it works with 32K or SAMS 1Meg cards and even had calls for using Hard drives like the cataloger in RXB will catalog Directories, no other XB has this feature. Matter of fact RXB has many features no other XB made can match. Quote Link to comment Share on other sites More sharing options...
+jedimatt42 Posted February 7, 2017 Share Posted February 7, 2017 I tried that and while I am able to send character data to the XBee, I have not been able to successfully receive data back as I kept getting I/O ERROR 26 (device not connected). I think that process requires the DTR/CTS lines to be connected, something the XBee does not have. Using CALL IO on the other hand allows for extreme flexibility in how the serial transmission is happening, and is likely faster as well... That's the part I missed... That must be why so many people built false null-modems, that bridge the TI's DTR and CTS to each other on one end, so only TX/RX get connected across devices. I always thought that was an unusual practice... Checkout the section here called 'loopback handshaking' : https://en.wikipedia.org/wiki/Null_modem Sadly the pictures is really tiny (but they are SVG, so ctrl-+ repeatedly to zoom in), but I bet you need to wire loopback handshaking for Data Set Ready, Carrier Detect, and Data Terminal Ready. Then the DSR for OPEN #1:"RS232..." would think the remote device is ready as soon as it asserts that itself is ready. Likewise you CTS/RTS pair may need looping on the TI side. But that's cool that you can bi-pass the strict serial protocol in the DSR, and go low level with CALL IO. Nice. I asked, because it slightly bothers me that no-one uses the DSR for serial ( for good reasons... but still ) Implementing the same CRU interface ends up being a requirement for any potentially new RS232 device. This is a place where TI's wonderful DSR abstractions for expandable peripherals broke down so rapidly as modem speeds out-paced 9600bps. -M@ Quote Link to comment Share on other sites More sharing options...
Tursi Posted February 7, 2017 Share Posted February 7, 2017 Vorticon, on 05 Feb 2017 - 07:39 AM, said: Thanks again Stuart. That worked. However, I ran into a perplexing issue: I have the remote Arduino send a single byte 0,1 or 255 in response to a command from the TI using the Serial.write() command from the Serial Arduino library. What I am receiving on the TI end is the correct byte but with the MSB set to 1. In other words, when the Arduino sends a 0, I get 128, with a 1 I get 129, but with 255 I get predictably 255. Just a hunch, but I'd start by checking my stop bit configuration on both sides? 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 7, 2017 Author Share Posted February 7, 2017 Just a hunch, but I'd start by checking my stop bit configuration on both sides? When I check CRU 9 after receiving a byte, there is no transmission error detected, so I'm not sure what's going on yet. I think that the issue lies with the Xbee devices as these things have a myriad of settings and I might be missing a subtle configuration point... Quote Link to comment Share on other sites More sharing options...
Tursi Posted February 7, 2017 Share Posted February 7, 2017 I don't think an extra stop bit will cause a transmission error (remember it's very basic framing and parity check only if that's enabled), but it is possible to get misaligned frames with incorrect stop or parity config on one side. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 8, 2017 Author Share Posted February 8, 2017 I don't think an extra stop bit will cause a transmission error (remember it's very basic framing and parity check only if that's enabled), but it is possible to get misaligned frames with incorrect stop or parity config on one side. I did verify all the comm parameters, and everything is as it should... What I'm going to do next is play with the parameters a bit and see if I hit on a combination that works. Maybe use 2 stop bits instead of one? BTW, when I checked the contents on the receive buffer with nothing connected to the serial port, I got 128 consistently, not 0. Now that is strange... Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted February 8, 2017 Share Posted February 8, 2017 Can you post the XB code you are using to receive the byte? Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 8, 2017 Author Share Posted February 8, 2017 Can you post the XB code you are using to receive the byte? Here you go: 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 125 CALL IO(3,1,CRU+16,1) !ACTIVATE RTS 130 PRINT "SENT: ";K::CALL IO(3,8,CRU,K) !LOAD EMIT REGISTER AND SEND BYTE 135 CALL IO(3,1,CRU+16,0) !INACTIVATE RTS 140 CALL IO(2,1,CRU+21,BYTEIN)::IF BYTEIN=0 THEN 140 !CHECK IF RECEIVE BUFFER HAS A BYTE IN IT 150 CALL IO(2,8,CRU,DATAIN) ! READ RECEIVED BYTE 160 PRINT "RECEIVED: ";DATAIN 170 GOTO 120 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted February 8, 2017 Author Share Posted February 8, 2017 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. 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.