Shop OBEX P1 Docs P2 Docs Learn Events
Simultaneous serial send and receive using only 1 interrupt routine. — Parallax Forums

Simultaneous serial send and receive using only 1 interrupt routine.

Mag748Mag748 Posts: 269
edited 2006-11-12 15:27 in General Discussion
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

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

Comments

  • pjvpjv Posts: 1,903
    edited 2006-10-24 00:30
    Hi Marcus;

    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)
  • Mag748Mag748 Posts: 269
    edited 2006-10-24 01:01
    Hmm, ok. I was afraid of that. The ISR I have now is all assembly, as you can imagine, and I have almost no clue how it works. I understand that it constantly looks at a pin and detects whether it is high or low, and when it detects a change, it records a new bit to a buffer, which eventually becomes a new byte in an 'incoming message stack' or something. I would have no way of figuring out how to reverse this process. Do you have any sample programs or resources that you know of?
    Thank you very much,
    Not at least I know it is very possible.
    -Marcus

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • pjvpjv Posts: 1,903
    edited 2006-10-24 01:15
    Hi 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)
  • Mag748Mag748 Posts: 269
    edited 2006-10-24 02:30
    Ok, I have found your project submission you mentioned. It looks very helpful. I will study it over the next few days. And, yes, I have the SX-Tech board with an SX-Key.
    Thank you very much Peter.
    -Marcus

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • Mag748Mag748 Posts: 269
    edited 2006-11-05 22:19
    Hello again.

    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

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • BeanBean Posts: 8,129
    edited 2006-11-06 01:32
    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
    ·
  • Mag748Mag748 Posts: 269
    edited 2006-11-06 02:16
    Bean,
    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

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • YendorYendor Posts: 288
    edited 2006-11-10 17:54
    Marcus - like the sound of your project as I'm working on something similar. I'd like to sync with MTC as well as generate MTC, working on the sync'ing concepts now.

    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
  • BeanBean Posts: 8,129
    edited 2006-11-10 19:02
    Marcus & 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
  • BeanBean Posts: 8,129
    edited 2006-11-11 01:56
    Try this guys...


    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
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2006-11-11 04:13
    Hey Bean,

    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
  • BeanBean Posts: 8,129
    edited 2006-11-11 12:24
    Execellent point Phil. I didn't think about if the data changed just after the interrupt sampled it.

    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
    ·
  • YendorYendor Posts: 288
    edited 2006-11-11 15:58
    Bean,
    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:

    SerialOut PIN RA.1 INPUT 'MIDI Out - Open Collector/Hi-Z
    

    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

    attachment.php?attachmentid=73788
    607 x 720 - 43K
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2006-11-11 18:10
    There indeed are a lot of ways to do this.· If you have Guenther's text, that may be easier to guide you through it.

    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."········
    ···················· Tropical regards,····· G. Herzog [noparse][[/noparse]·黃鶴 ]·in Taiwan

    Post Edited (Kramer) : 11/11/2006 6:14:55 PM GMT
  • YendorYendor Posts: 288
    edited 2006-11-11 20:22
    Kramer,

    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).
    attachment.php?attachmentid=73789

    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
    607 x 193 - 12K
  • BeanBean Posts: 8,129
    edited 2006-11-12 15:27
    Okay here is a version of the SX/B serial interrupt code that uses 3x the baud rate.

    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
Sign In or Register to comment.