Simultaneous serial send and receive using only 1 interrupt routine.
Mag748
Posts: 269
Hello,
·
I currently have a fully functioning SX program that I would like to upgrade. Right now, the only thing that it does is receive a serial stream and decodes the data, updating an LED display. I would like to add a function which will send a serial stream as well as listen to the original incoming serial stream for instructions. The serial stream that I would like to send is midi time code. So I would need some way of keeping track of time. I looked around for a ‘stopwatch’ chip or something that keeps time faster than just the DS1620 (at least 1/30 of a sec). Using the ISR that I already have (which I am using to receive the serial data) can I use it to send data as well? Luckily it’s the same baud and everything. So, ideally, is there a way to send, receive, AND keep track of time all in the same ISR?
·
I could probably figure out the keeping track of time part fairly easy. Simply knowing how many clock cycles equal one thirtieth of a second. And then keeping a counter or something. I am not that experienced with interrupts though.
·
Thank you for reading,
Marcus
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·
I currently have a fully functioning SX program that I would like to upgrade. Right now, the only thing that it does is receive a serial stream and decodes the data, updating an LED display. I would like to add a function which will send a serial stream as well as listen to the original incoming serial stream for instructions. The serial stream that I would like to send is midi time code. So I would need some way of keeping track of time. I looked around for a ‘stopwatch’ chip or something that keeps time faster than just the DS1620 (at least 1/30 of a sec). Using the ISR that I already have (which I am using to receive the serial data) can I use it to send data as well? Luckily it’s the same baud and everything. So, ideally, is there a way to send, receive, AND keep track of time all in the same ISR?
·
I could probably figure out the keeping track of time part fairly easy. Simply knowing how many clock cycles equal one thirtieth of a second. And then keeping a counter or something. I am not that experienced with interrupts though.
·
Thank you for reading,
Marcus
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Comments
Yes, it can readily be done, and simultaneously keep track of time as well..... I do lots of these concurrent task programs.
To do this, you will need to write it in assembler though.
Cheers,
Peter (pjv)
Thank you very much,
Not at least I know it is very possible.
-Marcus
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I'm sure I can point you in the right direction, and help if needed.
I trust you have someting programmable like an SX Tech or ProfDevelopment board and an SX-Key ?
To do simultaneous functions efficiently, you will want to use a scheduler.... kind of like a simple minded real-time operating system. You can find an example in my previous submission to the Parallax contest.
It is well commented, and if you are rusty on interrupts, then becoming familiar with that is an absolute "must". So study that example, and we'll go from there.
Cheers,
Peter (pjv)
Thank you very much Peter.
-Marcus
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I had no idea there were so many different ways to do what I wanted. I found about 6 different app notes in the download section, excluding Peter's TROS ducumentation. I feel completely overwhelled with information and I have no idea where to start. The SX circuit that I have now is set up to run at 20 MHz and most of the VP/Dual UART demos all run at 50MHz. Is it easy to change them to 20MHz? I can of course change the FREQ directive, but I cant find any RETI commants to determine how often the interupt would run. Also, I am not really sure where to put my code in the template.
Basically, what I need is a single UART, one that can send and recive bytes at 31,250 bps.
Also, I need a timer that would set a flag every 1/60 seconds.
Even though there is so many demos and so much documentation, I am having a lot of difficulty implementing this.
-Marcus
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I usually start with an interrupt that is 2x the baud rate. That would be 62500. And you 1/60th would be 1042 of those interrupts so you'll need a counter for that.
You'll need a variable to keep track of what bit you are sending and receiving. Sending is easier than receiving.
Sending you'll just put the next bit on the pin every 2nd interrupt.
Receiving you'll wait until you get an idle state, then wait to get the start bit (always will be opposite of idle), then wait "3" interrupts to sample the first bit, then 2 interrupts afterwards to get the rest of the bits.
If I get some time I'll write up some code for ya.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
"People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin
·
Thank you so much. That will definately get me started.
Btw, I bought 5 of those 4 digit LED displays. Looking forward to getting them.
-Marcus
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
If you haven't already, I also recommend the following:
Column #117: Timing is Everything in the Nuts&Volts section for some assembly explanation from Jon Williams on the Rx, as it is used in his Advance Midi Reciever project, which you are probably well aware of by now.
Also, I believe this code was borrowed from Chip Gracey's vitrual UART that is in Gunther's book that covers both Tx and Rx, in assembly. Every line has comments! See pgs 180-185, and the text downloads sections (TUT040 is the source code).
Also, check out Paul Messick's web site.: http://www.maxmidi.com/diy/metro/index.html
He has source code in there using a PIC16C54 that using incoming MTC for a metronome, and provides nice comments, as well. This will be an effective tool to work on for our drummer trying to play with a sequencer backing track, as we don't have a set of headphones big enough to wrap around his head, but then again he DOES get distracted with colored lights!
Bean - would it help that your favorite pest is interested in your sample, as well?
Rodney
I have the code done, but I need to test it. Hopefully I'll be able to do that this weekend.
The interrupt runs at twice the baud rate. So if you need 31250 Baud, the interrupt will run at 62500. So at 20Mhz that gives about·320 clocks, the routines should only use about 100-ish clocks. So that is about 1/3 of the processors time. If you run at 50MHz (recommended), you will have 800 clocks per interrupt. So the routines will only use 1/8 of the processors time.
I'll post the code if someone wants to test it for me [noparse];)[/noparse]
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
"People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin
Post Edited (Bean (Hitt Consulting)) : 11/10/2006 7:18:32 PM GMT
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
"People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin
I just read your post from 11/5.
I've always used 3x the baudrate for receive. The reason is this: at 2x, if the first low in the start bit is detected near the middle of its transmitted frame, the first data bit won't be sampled until very near the end of its frame. Any slight mismatch between baudrates, and you could already be into the next bit. And baud mismatches only get exacerbated as you near the end of the byte.
At 3x, this can't happen. Here, you wait for the start bit, then wait four timer interrupts to sample the first bit, then three thereafter. The first detected low in the start bit can't be more than 1/3 through the bit. Add 4 clocks to this, and you can't be more than 2/3 through the first data bit. At the other end, if the first start bit sample occurs right when the start bit goes low, the first data bit sample can't be less than 1/3 through the first data bit. So in every case, you're sampling data bits in their middle third.
At 3x, you've also got a chance to resample the start bit one interrupt after it's detected to see if it was just a noise glitch.
'Just a suggesiton...
-Phil
I'll change that. I also want to post an optimized version.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
"People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin
·
I bet your templates are better than most peoples source code - I'd take an alpha version off of you any day!
I wasn't expecting you to DO the code for us... But it is nice to see it in SX/B!
So, that does it!· You're getting something for Christmas, but I just googled Hitt, and it seems to be·from a Jewish decendant...So does this mean I need to send you 8?··;o)·
Since we're discussing, referencing Jon's·N&V's column·#117 "Timing is Everything",·he mentions that we should sample 4X per bit period for interrupt-driven serial input.· So don't we need to sample 4X the bit period for one serial in or is that over engineering?·Then·the challenge is·to make sure we're not Tx'ing when an interrupt occurs, or lose Rx bits when we're Tx'ing.·· In that point I can see to alternate portions of the interrupt which have a sampling of 4X and increasing the effective baud rate by 2 (or increasing the sampling to·8X - same thing).· This seems like we can then change for every instance of serin/out needed (e.g. 3 instances = 12X), but let's not go there now...
Just for grins, I put together the chart·below·for 2X, 4X, 8X and 12X the bit rates while increasing·the MIDI Baud.··
Also, Bean, since we're mimicing Serial IN/OUT using SX/B bitbanging, we still need to have an Open Collector for output on Midi.· So we're handling the "T" part of the baud rate option through code, and the "O" part, do we again just need to declare the pin as INPUT for serial out to make it Hi-Z?· As in:
Bean, we all appreciate how generous you are with your intellectual property and your support.· You've really enlightend me!· "I LOVE YOU, MAN!"
Rodney
Guenther's tutorial Tu40.scr will do it.· I think it is nearly complete excepting that it is echoing.· You would have to redirect either the Rx or Tx to another RAM location.· Maybe you would have to add a couple of flags too.
He samples at 16x and operates at 50Mhz.· He used the 8-n-1 serial which is most popular because of the least code to write.· 7bit or Parity or more Stop bits require a lot of little modifications.· I have been working with making it convert parity to none and vise-versa.
Jon Williams published an article that said that the general consensus was that a minimum of 4x sampling was optimal.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"If you want more fiber, eat the package.· Not enough?· Eat the manual."········
Post Edited (Kramer) : 11/11/2006 6:14:55 PM GMT
It took me a minute to find the 16X you're mentioning,·but I see what you're saying.· Here's the chart with 16X sampling, and added the·19,200 baud from the VP UART code (the resultant RTCC for 19200 should be rounded up).
So we have 3X, 4X and 16X.· Could it be a power of two problem?·
One·serial-in·it's 41.· For serin/serout it's 42?· But it seems like that·42·would be needed for two rx's.
I find the whole thing very interesting...
Rodney
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
"People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin