Jump to content
IGNORED

Serial port control with RXB


Vorticon
 Share

Recommended Posts

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...

Link to comment
Share on other sites

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.
Link to comment
Share on other sites

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

Link to comment
Share on other sites

 

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!

  • Like 1
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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
  • Like 3
Link to comment
Share on other sites

 

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. ;-)

  • Like 1
Link to comment
Share on other sites

 

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!

  • Like 3
Link to comment
Share on other sites

 

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.)

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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 by Stuart
  • Like 1
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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@

Link to comment
Share on other sites

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...

  • Like 2
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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@

Link to comment
Share on other sites

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?

  • Like 1
Link to comment
Share on other sites

 

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...

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...