Searching \ for '[SX] IRC is a few cycles short' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/ubicom/devices.htm?key=sx
Search entire site for: 'IRC is a few cycles short'.

Exact match. Not showing close matches.
PICList Thread
'[SX] IRC is a few cycles short'
2006\02\15@202000 by ShadowsSoldiern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, ShadowsSoldier wrote:

Hi folks, I am having trouble understanding why one of my interrupt routines is going at every 62 or 63 cycles instead of every 64. When I don't use conditional instructions such as JNB and break it out from the rest of the program in a new one, it hits every 64 cycles like a charm. I thought the mov w, #-64 and then retiw took care of this but I am still coming up a few cycles short in my program below. Just to give you background on what this code does is that it dynamically reconfigures the IRC to switch back and forth betwen 40KHz and 250Hz while alternating the output between two different pins every time 40KHz occurs. It works ok, I just don't understand the small descrepancy in cycles.

FYI the intital state is set to run the 40 KHz first. The routine is contained in the IRC under :RTCC and also the first configuration of the RTCC. Sorry about the uneven indents and stuff. Thats not how it looks in my editor though.


Thanks to anyone that can help.


Device SX28L, Turbo, Stackx, OSCHS3
IRC_CAL IRC_SLOW
FREQ        5_120_000

RESET Start
ORG $000                                                
Interrupt                                              ; Interrupt Routine - always starts at $00
DEC CycleCount                                            ; countdown to 255
JNB CycleCount.7, WRITE                            ; cyclecount.7 = 0, toggle? go to accessment
;----------------------------------------------------------------------------
                                                         ; underflow occurs, reconfigure IRC
NOT IRCState                                          ; flip state
JNB IRCState.0, :RTCCPSA
:RTCC                Mov w, #%1100_0000                ; initialize RTCC = 191
               Mov rtcc, w                
               Mov w, #%1001_1111                    ; reconfigure as RTCC only!
               Mov !option, w
               Mov w, #%0000_0110                ;  
               Mov CycleCount,w                    ; set cyclecount to 6 (bit 7 ON on underflow)- 64 cycles = 12.5 us
               NOT TX1TX2                              ; flip transmitter select
                     reti                                             ; configuration complete
:RTCCPSA        Mov w, #%0000_0001
               Mov RTCC, w                              ; initialize RTCC to 1
               Mov w, #%1000_0001                ; reconfigure RTCC with PSA 1:4
               Mov !option, w
               Mov w, #%0001_0100
               Mov Cyclecount, w                ; set counter to 20 (bit 7 ON on underflow)- 20 cycles prescaled = 4.0 ms
               reti        
;----------------------------------------------------------------------------
WRITE                JNB IRCState.0, RetRTCCPSA        ; jump to prescaler return if IRCState=0  
               JNB TX1TX2.1, :Ra                ; toggle a port during RTCC - but which?
               NOT RB                                ; write RB
               JMP RetRTCC        
:Ra                NOT RA                                ; write RA
RetRTCC                Mov w, #-64
               Retiw
RetRTCCPSA        Retiw
Org $08

CycleCount                ds 1        
TX1TX2                        ds 1
IRCState                ds 1
IRCRecon                ds 1
Org $100
Start
;load predefined registers
       Clr Cyclecount                        ; trigger var
       Clr TX1TX2                        ; Tx1/Tx2 (0/1)
       Clr IRCState                        ; 0 = RTCC w/ PSA , 1 = RTCC
       Clr IRCRecon
; de-glitch initial state
       Mov w, #%0000
       Mov Ra, w                ; set register A output to digital LOW
       Mov w, #%0000_0000        
       Mov Rb, w                ; set register B output to digital LOW
       Mov w, #%0000_0000
       Mov Rc, w                ; set register C output to digital LOW
; configure ports
       Mov M, #$0f                ; access TRIS mode
       Mov W, #%0000                ; bits 0-3 are outputs
       Mov !Ra, W                ; make Ra0-Ra3 outputs        
       Mov W, #%0000_0000        ; all bits output
       Mov !Rb, W                ; set Port B pins to output
       Mov W, #%0000_0000        ; all bits output
       Mov !Rc, w                ; set Port C pins to output
; set intial conditions
       
       Not TX1TX2                                ; select TX1 (indirect)
       Not IRCState
       JNB IRCState.0, :RTCCPSA
:RTCC                Mov w, #%1011_1111                ; initialize RTCC = 191
               Mov rtcc, w                
               Mov w, #%1001_1111                ; reconfigure as RTCC only!
               Mov !option, w
               Mov w, #%0000_0110                ;  
               Mov CycleCount,w                ; set cyclecount to 6 (bit 7 ON on underflow)
               JMP Main
:RTCCPSA        Mov w, #%0000_0001
               Mov RTCC, w                        ; initialize RTCC to 0        
               Mov w, #%1000_0001                ; reconfigure RTCC with PSA 1:4
               Mov !option, w
               Mov w, #%0000_0000
               Mov Cyclecount, w                ;
MAIN
JMP Main
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\15@204038 by PJMontyn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, PJMonty wrote:

Why are you using reti and retiw instructions in your interrupt routine?  Only the retiw uses the value of W to properly update the RTCC count.  Also, unless you are really pressed for cycles, it's a good practice to have only a single exit point in any routine, but especially interrupt routines.  Why?  Well, using your interrupt as an example, suppose you need to change the interrupt rate.  If you have multiple places where you set W and then do an retiw, you'll have to find all of them and change all of them.  If you have a single exit point, then you only have a single place to update.

[list]Thanks,
PeterM[/list]
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m109673
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\16@143847 by amillern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, amiller wrote:

Remember that JNB is actually two instructions hidden in one.

JNB = SB and JMP.

Take a look at the assembler output listing file, and the assembled SX instructions/timing should be more clear.

-AGM-
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m109797
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\16@192712 by ShadowsSoldiern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, ShadowsSoldier wrote:

Doesn't retiw take into account the two instructions hidden in one? If not this would explain the discrepancy.

---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m109847
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\16@210829 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi Bebop;
A peculiarity of the SX is that every time you write to or test (but not read) the RTCC, it stalls the RTCC count for 2 (I think) cycles. Perhaps something to do with the pipeline, I'm not sure.

So you are best not to mess with the RTCC, just let it roll over and do its thing.....just load w with an appropriate value for each of the interrupt periods, and then RETIW. That will properly take care of things.

And, yes, compound instructions are counted properly. The assembler turns them into their appropriate number of elements.

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m109860
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\17@011413 by PJMontyn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, PJMonty wrote:

Bebopalot,
I think you need to get a better conceptual grasp of what the retiw instruction is doing in order to understand how it works.  I believe a lot of people are rather mystified by the whole retiw with a negative number thing, so perhaps this will help.

Imagine that the RTCC is your digital alarm clock.  If you don't change the alarm time on it, every 24 hours it will go off at the same time.  You don't need to do anything special, it just happens.  Now suppose that for some reason you need to take some medicine every three hours starting at midnight.  What you could do is set your alram clock to go off at midnight.  You would then get out of bed, take your medicne, go back to bed, and before falling asleep you'd set the alarm to go off at 3 AM.  When the alarm went off, you'd repeat the process, only this time when you got back into bed you'd set the alarm for 6 AM.  When the alarm went off at six, you'd do the same thing only this time you'd set it for 9 AM, etc, etc, etc.

Now, the nice thing about this is that no matter how long it took you to get up and take your medicine, when you set the alarm it would be for some absolute time (3 AM, 6 AM, etc) and not a relative time such as "3 hours from now."  By doing it this way, you allow yourself flexibility (perhaps you went to the bathroom or ate a snack one of the times you got up to take you rmedicine) in the amount of time your "medicine" task took, but the time between getting up was always a consistent and accurate 3 hours.  The key is that the clock kept running and keeping track of time while you got your medicine, and you manually calculated what time to set the alarm for to be three hours from when it woke you up.

This is essentially what the negative number in the retiw instruction does.  When the RTCC interrupt goes off, the CPU jumps to the interrupt code and starts executing it.  Depending on what it's doing, sometimes it takes more or less time for the interrupt code to execute depending on things like conditional code paths.  The whole time you're executing the interrupt, the RTCC is still going, just like your clock.  However, when you get to the end of the interrupt code, there is that nice retiw with a negative number.  That negative number is added to the current value of RTCC (whatever it is) and, just like you setting your alarm to be at the next 3 hour increment, it automatically causes the RTCC value to be jumped ahead so that it goes off at the right time.
If you specify -26, the RTCC will be jumped ahead so that it generates an interrupt 26 clocks cycles from the time the current one went off.  If you specify -100, the time between interrupts will be 100 cycles.  As long as your interrupt code takes less time than the number of cycles in your RTCC time interval, you're golden.  Your interrupt could take 9 cycles on one interrupt and 62 on the next, but when your interrupt is done and the "retiw #-100" is executed, the next interrupt will happen 100 clocks from when the current one started.  No muss, no fuss.  The CPU does all the work needed to make this happen.  
Finally, by adding in the prescaler to the RTCC, you can lengthen  the amount of time between interrupts.  If the RTCC is feed with no prescaler, then every clock cycle causes the RTCC clock to increment (or decrement, I cna't remember if it counts up or down) to the next value.  This means your interrupt period can be no longer than 255 clocks long.  At 50 MHz, that's a pretty short amount of time.  However, if you need more time, set the prescaler to something other than 1:1 and you'll get that amount of time increase.  If the prescaler is 4:1, then the RTCC value will get changed every four clocks, meaning that your maximum of 255 is now 255 * 4 = 1020 cycles.

Hopefully this will help make the workings of the RTCC and the retiw instruction a little clearer.  The key to remember is that as the person writing code, you can trust that the you'll get consistent time between interrupts regardless of any varying amount of time spent in the interrupt code as long as the overall interrupt execution time is less than the interrupt period.

[list]Thanks,
PeterM[/list]
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m109876
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\17@111235 by James Newtonn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, James Newton wrote:

Peter, that was lovely...

...I've put it on a page at sxlist.com if that is ok with you?

http://www.sxlist.com/techref/ubicom/RETIWinISRs.htm
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m109949
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\17@140344 by ShadowsSoldiern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, ShadowsSoldier wrote:

Ok, but this is the change that brought about a correction:

I changed the code  "NOT Ra" to:

NOT output1
mov w, output1
mov Ra, w
Now its hitting it every 64 cycles exactly.

The NOT command to output register Ra was causing me problems.

BBAL
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m109984
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\18@063434 by ShadowsSoldiern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, ShadowsSoldier wrote:

Here is my modified code. The problem I have identified still mystifies me. In short, depending on the value of TX1TX2 (0000_0000 or 1111_1111) the IRC rountine takes one of two paths. In one path the cycle count in the SXSim is always 64 (what I need) in the other path it is always 63 (when TxT1 is set to 1111_1111). Each path when selected will repeat for a total of six interupts - so I don;t see why there is a discrepancy. Does anyone else see what I am saying?

BBAL
;5.120 MHz version
Device SX28L, Turbo, Stackx, OSCHS3
IRC_CAL IRC_SLOW
FREQ        5_120_000

RESET ResetEntry
ORG 0                                        
Interrupt                                        ; Interrupt Routine - always starts at 0
DEC CycleCount                                            ; countdown to 255
JNB CycleCount.7, WRITE                                ; cyclecount.7 = 0, compare
;----------------------------------------------------------------------------
                                               ; underflow occurs, reconfigure IRC
               Setb Recon.0                        ; Recon to TRUE
Exit                JNB IRCState.0, TermPSA
TermRTCC        Mov w, #-64
Go                Retiw                                ; single exit point
TermPSA                Mov w, #-%1111111
               JMP Go                        
;----------------------------------------------------------------------------
WRITE                JNB IRCState.0, TermPSA                ; jump to prescaler return if IRCState=0  
               JNB TX1TX2.0, WriteRa                ; toggle a port during RTCC - but which?
               NOT output1                        
               Mov w, output1
               Mov Rb, W                        ; write RB
               JMP TermRTCC                        ; terminate write RB        
WriteRa                NOT output2
               Mov w, output2                        
               Mov Ra, w                        ; write RA
               JMP TermRTCC                        ; terminate write RA

Org 08

CycleCount                ds 1        
TX1TX2                        ds 1
IRCState                ds 1
IRCRecon                ds 1
Output1                        ds 1
Output2                ds 1
Recon                        ds 1

Org 100
ResetEntry
;load predefined registers
       Clr Cyclecount                        ; trigger var
       Clr TX1TX2                        ; Tx1/Tx2 (0/1)
       Clr IRCState                        ; 0 = RTCC w/ PSA , 1 = RTCC
       Clr Recon                        ; 0 = don't reconfigure, 1 = reconfigure
       Clr Output1                        ; toggle state TX1
       Clr Output2                        ; toggle state TX2
; de-glitch initial state
       Mov w, #%0000
       Mov Ra, w                ; set register A output to digital LOW
       Mov w, #%0000_0000        
       Mov Rb, w                ; set register B output to digital LOW
       Mov w, #%0000_0000
       Mov Rc, w                ; set register C output to digital LOW
; configure ports
       Mov M, #$0f                ; access TRIS mode
       Mov W, #%0000                ; bits 0-3 are outputs
       Mov !Ra, W                ; make Ra0-Ra3 outputs        
       Mov W, #%0000_0000        ; all bits output
       Mov !Rb, W                ; set Port B pins to output
       Mov W, #%0000_0000        ; all bits output
       Mov !Rc, w                ; set Port C pins to output

       
; Initialize
       
       Not TX1TX2                                ; select TX 1/2 toggle this on and off and you get a 63-64 cycle difference
       Not Recon                                ; toggle reconfigure
       
Start
JNB Recon.0, Loop                                        ; if recon = FALSE do not reconfig
Call Reconfigure
Loop
JMP Loop

; Subroutine
Reconfigure
               NOT IRCState                        ; flip state
               JNB IRCState.0, PSA
               Mov w, #%1100_0000                ; initialize RTCC = 191  
               Mov rtcc, w                
               Mov w, #%1001_1111                ; reconfigure as RTCC only!
               Mov !option, w
               Mov w, #%0000_0110                ;  
               Mov CycleCount,w                ; set cyclecount to 6 (bit 7 ON on underflow)- 64 cycles = 12.5 us
               NOT TX1TX2                        ; flip transmitter select
               JMP EndRoutine                                ; configuration complete
PSA                Mov w, #%0000_0001
               Mov RTCC, w                        ; initialize RTCC to 0        
               Mov w, #%1000_0001                ; reconfigure RTCC with PSA 1:4
               Mov !option, w
               Mov w, #%0000_0001                ; Mov w, #%0001_0100
               Mov Cyclecount, w                ; set counter to 20 (bit 7 ON on underflow)- 20 cycles prescaled = 4.0 ms
               Mov w, #-%1111111                ; jump ahead to call IRC every 256 cycles
EndRoutine        Clrb Recon.0                        ; set reconfigure to false
               Ret
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m110050
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\19@194233 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi Bebop;
I'm still in ransit on my way back home from the "Propeller unveiling" at Parallax. Perhaps I will get a chance to peek at and try your code tomorrow. I'm sure the answer is straigt forward.

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m110267
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\19@221537 by ShadowsSoldiern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, ShadowsSoldier wrote:

Thanks Peter, I'm all ears.

Stumped
BBAL
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m110293
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\20@081530 by PJMontyn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, PJMonty wrote:

James,
Sorry to take so long to reply, I was travelling - of course you can post it anywhere you like.  It took long enough to write (twice - the 1st version got bogged down in technical details) that I'm glad it struck a chord.

[list]Thanks,
PeterM[/list]
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m110337
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\20@083640 by PJMontyn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, PJMonty wrote:

Bebopalot,
Well, one tricky aspect to your dilemma is that you are assuming that SxSim is correct.  No slight on the exceptional work of  Guenther, but simulators always run the risk of being incorrect compared to the hardware.  The good news is, you've probably discovered a bug in SxSim that Guenther will likely fix.  The bad news is that you've spent a lot of time worrying about details that are almost certainly correct on the real hardware.  
Basically, if you have a single exit point in your ISR, you're using the retiw instruction to return form it, and the maximum execution path of your ISR is shorter by 6 (or is it 9?) cycles than the duration of the ISR period, then your code will execute at a consistent number of cycles each time.  This is pretty much the guarantee that SX users depend on when coding ISR routines, and a key reason for many people to use the SX in the first place.  Personally, at this point, I would either assume a bug in SxSim or find a way to verify the cycle count using external hardware (such as an oscilloscope) before I would spend another moment worrying about the apparent one cycle discrepancy.

BTW, this doesn't mean that every time you find a discrepancy betwen your expectations and what SxSim says that you automatically assume a bug in SxSim.  On the contrary, I think your diligence in figuring out this problem and the effort you've undertaken on the assumption that the problem is in your code, is the absolute correct way to proceed with these sorts of problems.  Most people blame the assembler/compiler/IDE/chip long before they ever assume that their code was wrong.  However, at some point, when you find that your solar system simulator shows that days are really 25 hours long for half the year and 23 the other half, you have to assume a flaw in the simulator and find an independent means of verifying the error since real world experience shows that days are consistently 24 hours long.

[list]Thanks,
PeterM[/list]
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m110347
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\20@124839 by ShadowsSoldiern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, ShadowsSoldier wrote:

PeterM
I checked with my o-scope and the bursts seem to hover around 40.00 KHz for a while and sometimes deviate. But that may be my digital oscope. If you all recall I disembarked on the IRC path because an experienced forum member cited that using "hard coding" with nops and nested loops really underutilized the clocking of a jitterless interupt. Now I have a question before me, which may not have any practical relevance: which code do I use? My hard coded loop or my code above with the interupts? I don't trust my own digital scope to give me the answer. For both the hard-coded and IRC versions the bursts hang around 40.00 KHz and then fluctuate. Maybe I should get a freqeuncy counter to verify. In any event, I am going to go ahead now and I a least have the option of either version in the future to use and see if one or the other makes a difference. I want my signal just as clean as can be.

I really have learned a lot in this problem! I feel a little more experienced with the SX now!

BBAL
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m110435
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\20@133634 by beann/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, bean wrote:

If you post your code I will check it with a frequency counter.
Of course the frequency will only be as accurate as your master clock source.
Bean.

---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m110446
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\21@091821 by ShadowsSoldiern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, ShadowsSoldier wrote:

Thanks Bean, here is my "IRC version". I'll post the "hard coded" in the next post. Total = 2 versions. Burst should be 40KHz.


;5.120 MHz version
Device SX28L, Turbo, Stackx, OSCHS3
IRC_CAL IRC_SLOW
FREQ 5_120_000

RESET ResetEntry
ORG 0
Interrupt ; Interrupt Routine - always starts at 0
DEC CycleCount ; countdown to 255
JNB CycleCount.7, WRITE ; cyclecount.7 = 0, compare
;----------------------------------------------------------------------------
; underflow occurs, reconfigure IRC
Setb Recon.0 ; Recon to TRUE
Exit JNB IRCState.0, TermPSA
TermRTCC Mov w, #-64
Go Retiw ; single exit point
TermPSA Mov w, #-%1111111
JMP Go
;----------------------------------------------------------------------------
WRITE JNB IRCState.0, TermPSA ; jump to prescaler return if IRCState=0
JNB TX1TX2.0, WriteRa ; toggle a port during RTCC - but which?
NOT output1
Mov w, output1
Mov Rb, W ; write RB
JMP TermRTCC ; terminate write RB
WriteRa NOT output2
Mov w, output2
Mov Ra, w ; write RA
JMP TermRTCC ; terminate write RA

Org 08

CycleCount ds 1
TX1TX2 ds 1
IRCState ds 1
IRCRecon ds 1
Output1 ds 1
Output2 ds 1
Recon ds 1

Org 100
ResetEntry
;load predefined registers
Clr Cyclecount ; trigger var
Clr TX1TX2 ; Tx1/Tx2 (0/1)
Clr IRCState ; 0 = RTCC w/ PSA , 1 = RTCC
Clr Recon ; 0 = don't reconfigure, 1 = reconfigure
Clr Output1 ; toggle state TX1
Clr Output2 ; toggle state TX2
; de-glitch initial state
Mov w, #%0000
Mov Ra, w ; set register A output to digital LOW
Mov w, #%0000_0000
Mov Rb, w ; set register B output to digital LOW
Mov w, #%0000_0000
Mov Rc, w ; set register C output to digital LOW
; configure ports
Mov M, #$0f ; access TRIS mode
Mov W, #%0000 ; bits 0-3 are outputs
Mov !Ra, W ; make Ra0-Ra3 outputs
Mov W, #%0000_0000 ; all bits output
Mov !Rb, W ; set Port B pins to output
Mov W, #%0000_0000 ; all bits output
Mov !Rc, w ; set Port C pins to output

; Initialize
Not TX1TX2 ; select TX 1/2 toggle this on and off and you get a 63-64 cycle difference
Not Recon ; toggle reconfigure
Start
JNB Recon.0, Loop ; if recon = FALSE do not reconfig
Call Reconfigure
Loop
JMP Loop

; Subroutine
Reconfigure
NOT IRCState ; flip state
JNB IRCState.0, PSA
Mov w, #%1100_0000 ; initialize RTCC = 191
Mov rtcc, w
Mov w, #%1001_1111 ; reconfigure as RTCC only!
Mov !option, w
Mov w, #%0000_0110 ;
Mov CycleCount,w ; set cyclecount to 6 (bit 7 ON on underflow)- 64 cycles = 12.5 us
NOT TX1TX2 ; flip transmitter select
JMP EndRoutine ; configuration complete
PSA Mov w, #%0000_0001
Mov RTCC, w ; initialize RTCC to 0
Mov w, #%1000_0001 ; reconfigure RTCC with PSA 1:4
Mov !option, w
Mov w, #%0000_0001 ; Mov w, #%0001_0100
Mov Cyclecount, w ; set counter to 20 (bit 7 ON on underflow)- 20 cycles prescaled = 4.0 ms
Mov w, #-%1111111 ; jump ahead to call IRC every 256 cycles
EndRoutine Clrb Recon.0 ; set reconfigure to false
Ret
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m110631
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\21@092136 by ShadowsSoldiern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, ShadowsSoldier wrote:

"Hard Coded" Version
;5.120 MHz version
Device SX28L, Turbo, Stackx, OSCHS3
IRC_CAL IRC_SLOW
FREQ        5_120_000

RESET MAIN
ORG $08                                                ;define word size for addresses
Hi_Counter        ds 1
Lo_Counter        ds 1
Long_Delay1        ds 1
Long_Delay2        ds 1
Burst_Count     ds 1

ORG $100

MAIN

; de-glitch initial state
Mov w, #%0000
Mov Ra, w                ;set register values port A to digital LOW
Mov w, #%00000000        
Mov Rb, w                ;set register values port B to digital LOW
Mov w, #%00000000
Mov Rc, w                ;set register values port C to digital LOW
; configure ports
Mov M, #$0f                ; access TRIS mode
Mov W, #%0000                ; bits 0-3 are outputs
Mov !Ra, W                ; make Ra0-Ra3 outputs
Mov M, #$0f                ; access TRIS mode
Mov W, #%00000000        ; all bits output
MOv !Rb, W                ; set Port B pins to output
Mov M, #$0f                ; access TRIS mode
Mov w, #%00000000        ; all bits output
Mov !Rc, w                ; set Port C pins to output

Generate_Bursts                
Mov w, #$03                ; set w=3
Mov Burst_Count,w        ; set burst counter for TX_1

;***** TRANSMITTER 1 *****
TX_1_Burst
;HI WAVE
               SetB Ra.0                                ; toggle RA.0 HI
       mov        w, #$0f                                        ; delay = 15 cycles
       mov        Hi_Counter, w                                ; load delay counter
Delay_1:
       decsz        Hi_Counter
       jmp        Delay_1
       NOP
       NOP        
;LO WAVE
               Clrb Ra.0                                ; toggle RA.0 LO
       mov        w, #$0f                                        ; delay = 15 cycles
       mov        Lo_Counter, w                                ; load delay counter
Delay_2:
       decsz        Lo_Counter
       jmp        Delay_2
Decsz Burst_Count
JMP TX_1_Burst
                                                       ; wait 18936 cycles - start 3.7ms delay
       mov        w, #$93
       mov        Long_Delay1, w
       mov        w, #$0B
       mov        Long_Delay2, w
TOF_Delay:
       decsz        Long_Delay1
       jmp        $+2
       decsz        Long_Delay2
       jmp        TOF_Delay
                                                       ;4 cycles (total 189340 cycles = 3.7ms)
       NOP
Mov w, #$03
Mov Burst_Count, w                                        ;reset burst counter to 3 for TX_2
;***** TRANSMITTER 2 *****
;HI WAVE
TX_2_Burst
               SetB Ra.3                                ; toggle RA.3 HI
       mov        w, #$0f                                        ; delay = 15 cycles
       mov        Hi_Counter, w                                ; load delay counter
Delay_3:
       decsz        Hi_Counter
       jmp        Delay_3
       NOP
       NOP        
;LO WAVE
               Clrb Ra.3                                ; toggle RA.3 LO
       mov        w, #$0f                                        ; delay = 15 cycles
       mov        Lo_Counter, w                                ; load delay counter
Delay_4:
       decsz        Lo_Counter
       jmp        Delay_4
Decsz Burst_Count
JMP TX_2_Burst
                                                       ; wait 18936 cycles - start 3.7ms delay
       mov        w, #$93
       mov        Long_Delay1, w
       mov        w, #$0B
       mov        Long_Delay2, w
TOF_Delay2:
       decsz        Long_Delay1
       jmp        $+2
       decsz        Long_Delay2
       jmp        TOF_Delay2
                                                       ;4 cycles (total 189340 cycles = 3.7ms)
       NOP
JMP Generate_Bursts                                        ;start again
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m110633
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\21@194252 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi Bebop;
I ran your code code posted today (Tuesday) this evening, and using a 50 MHz resonator (I don't have a 5.12 crystal), the interrupt gets triggered every 1.280 usec exactly. It never varies from that. I have a super scope that can trigger on event durations with better than 10 nsec precision, so I'm totally sure of the reading.

I found the code somewhat convoluted, and didn't try to decipher what it was trying to accomplish, but I wonder if there are some typing errors, but can't estimate if they would have any impact:

1.  Did you really mean to set the "Org" at reenty to 100......?  Isuspect you meant $100
2.  Did you really mean the line          "TermPSA       Mov w, #-%1111111" to only set 7 bits in W?  I suspect not..........It helps to use an underscore separator such as "mov    w,#-%1111_1111" then it's easier to spot such typos. Again I have no idea as to the impact of this, because the code never went there.

There could be other issues, so I ask you to describe in detail what is being attempted and how it is to be achieved, so we can have some better insight into what's expected.

I also expect there is a MUCH easier way to accomplish your goal; again a good explanation will help verify that.

Cheers,
Peter
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m110767
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\22@075108 by ShadowsSoldiern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, ShadowsSoldier wrote:

Hi Peter,
Overview of the program: I need the SX to hit a subcircuit with a burst of three 40KHz waves then pause for about 4.0ms; then hit a second subcircuit with a burst of three 40KHz waves, pause for about 4.0ms, then repeat the cycle. No two subcircuits should be on at the same time.

So designing the code, if we are going to use the interrupts then either we reconfigure the interrupts dynamically to equal the time intervals we need with 8 bit counters (simplicity) or we can use a single base interrupt but use multibyte counters to keep track of the number of 12.5us cycles during a 4.0ms pause = 320. I really haven't learned multibyte counters yet, so I chose to keep my counting 8 bit and reconfigure the interrupt dynamically to meet my needs. Certainly, if anyone had a better idea, I want to learn.

- It seems the program is working right, thanks for checking it out with your superscope.

- I am having trouble understanding what addresses to use and when in my code. I was getting an error earlier about my subroutine now being in the correct half of page of memory or something. I can't keep it straight when to use which addresses. $00 - interupts ; $08 - define word space ; $100 main program; subroutines = ??

-. As for "TermPSA Mov w, #-%1111111"  the assembler kept giving me a warning "Literal truncated to eight bits" until I reduced it by a digit to only 7 bits. What I was trying to acheive here was to "set the clock forward" to interupting every 255 cycles using the mov w, -x then retiw command but kept getting a truncation error. So I changed my value from "-%1111_1111"  to "-%1111111" which seemed to work but left me with a value of 127 instead of 255. I guess I could have put "-%0111_1111" which seems to work also. I don't understand why I am getting a truncation error with 255, -%1111_1111
Thanks Peter, and it is very interesting to hear the many different design angles on the code so far.

---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m110876
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\22@141557 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi Bebop;
To help you learn, I wrote an interrupt driven state machine for you to achieve what you are trying to accomplish. This is not the fastest or best way to implement it, but it should definitely help you in understanding what needs to be done.

The file in the attachment is more verbose than the abbreviated one listed here.

id 'Bebop4'                                                        ; Feb 22, 2006
;alternately provide 3 cycles of 40 KHz (12.5 uSec hi and 12.5 uSec lo) on two pins separated by about 4 mSec
 device sx28,oschs3,turbo,optionx                        ;new assembler
 freq 50_000_000                                              ;default run speed = 50MHz
 reset Init                                                        ;entry point for reset and power-up
ModeLevel equ $0D                                             ;mode for port ABC bit CMOS level selection (0)
ModePullup equ $0E                                            ;mode for port ABC bit pullup selection (0)
ModeTristate equ $0F                                         ;mode for port ABC bit output direction selection (0)
RTCCIntEnable = %1001_1111
IntConst            equ -125                                   ;2.5 uSec interrupt tick (125 * 20 nSec = 2500 nSec)
Port                  equ ra                                       ;
;flags
                 org $08                                           ;start of usable RAM space; independent of program memory
Flags           ds 1                                                ;
IntFlag  = Flags.0                                                ;use this bit as an indicator that interrupt has occurred
State           ds 1                                               ;
StateDurLow ds 1                                               ;low byte of 16 bit multi-use duration counter
StateDurHigh ds 1                                               ;high byte of 16 bit multi-use duration counter
CycleCounter ds 1                                               ;number of cycles in one burst
BurstBits       ds 1                                               ;holds the output value of the port bits
                 org $000                     ;interrupt routine always starts at beginning of program memory
Interrupt      setb IntFlag                 ;advise main routine that interrupt has occurred
                 mov w,Port                 ;get current state of port bits
                 and w,#%1111_1100     ;clear burst output bits
                 or w,BurstBits               ;merge in the current state of the burst bits
                 mov Port,w                  ;transfer the pre-calculated value for the port to the port
                 mov w,#IntConst          ;load w to interrupt again in 125 clocks..... 2.5 uSec
                 retiw                          ;return from interrupt
Init             ;Program starts here on reset and power up
                ;Initialize the ports
SetLevels     mov m,#ModeLevel        ;Set to 0 for CMOS levels
                 mov !ra,#%0000           ;
                 mov !rb,#%0000_0000   ;
                 mov !rc,#%0000_0000   ;
SetPullups    mov m,#ModePullup       ;Set to 0 for pullups
                 mov !ra,#%0000           ;
                 mov !rb,#%0000_0000   ;
                 mov !rc,#%0000_0000   ;
SetTris         mov m,#ModeTristate    ;Set to 0 for output
                 clr ra                           ;
                 mov !ra,#%0000            ;x,x,Burst1,Burst0
                 clr rb                           ;
                 mov !rb,#%1111_1111    ;
                 clr rc                           ;
                 mov !rc,#%1111_1111    ;
                 clr rtcc                        ;clear interrupt timer
                 mov !option,#RTCCIntEnable  ;enable interrupt
                 clr Flags                       ;
InitState      ;Initialize state and state duration timers high and low
                 mov StateDurLow,#1      ;trivial initial value
                 mov StateDurHigh,#1     ;trivial initial value
                 mov State,#StartBurst1  ;begin with outputting burst 1
Main            ;loop here waiting for an interrupt
                 sb IntFlag                    ;test for interrupt occurred
                 jmp Main                     ;not yet usec2_5       clrb IntFlag                  ;come here every 2.5 usec
                 decsz StateDurLow       ;test for state duration low to expire
                 jmp Main                     ;not yet
                 decsz StateDurHigh       ;wait for state duration high to expire
                 jmp Main                     ;not yet
                 mov pc,State               ;invoke next state after state duration has expired
StartBurst1  mov CycleCounter,#3     ;three cycles of (12.5 uSec hi then 12.5 uSec low)
SetBurst1Hi  mov BurstBits,#%0000_0001  ;set the port bit 0 hi
                 mov w,#SetBurst1Lo     ;load low address of next state which will set level low
                 jmp SetFreqDuration      ;set duration of current state 16 bit counter
SetBurst1Lo clrb BurstBits                 ;clear the port bit 0 lo
                 mov w,#SetBurst1Hi      ;load low address of next state which will set level high
                 decsz CycleCounter       ;derement every time one cycle is completed
                 skip                            ;effectively this makes the previous decsz equivalent to decsnz
                 mov w,#EndBurst1        ;load low address of next state which will time the 4 mSec interval
                 jmp SetFreqDuration      ;set duration of current state 16 bit counter
EndBurst1    ;set delay for a duration of 4 milliseconds that is 1600 ticks of 2.5 uSec; = (6*256) + 64
                 mov StateDurLow,#64    ;stay in this state for duration
                 mov StateDurHigh,#6+1  ;needs to be 1 more than required for dec instruction to time properly
                 mov State,#StartBurst2  ;set low address of next state which will start burst 2
                 jmp Main    ;
StartBurst2  mov CycleCounter,#3     ;three cycles of (12.5 uSec hi then 12.5 uSec low)
SetBurst2Hi  mov BurstBits,#%0000_0010  ;set the port bit 1 hi
                 mov w,#SetBurst2Lo      ;load low address of next state which will set level low
                 jmp SetFreqDuration      ;set duration of current state 16 bit counter
SetBurst2Lo  clr BurstBits                 ;clear the port bit 1 lo
                 mov w,#SetBurst2Hi     ;load low address of next state which will set level high
                 decsz CycleCounter      ;decrement every time one cycle is completed
                 skip                           ;effectively this makes the previous decsz equivalent to decsnz
                 mov w,#EndBurst2       ;load low address of next state which will time the 4 mSec interval
                 jmp SetFreqDuration     ;set duration of current state 16 bit counter
EndBurst2     ;set delay for a duration of 4 milliseconds that is 1600 ticks of 2.5 uSec; = (6*256) + 64
                 mov StateDurLow,#64    ;stay in this state for duration
                 mov StateDurHigh,#6+1  ;needs to be 1 more than required for dec instruction to time properly
                 mov State,#StartBurst1  ;set low address of next state which will start burst 1
                 jmp Main    ;
SetFreqDuration ;save address of next state (is in w) and set duration of current state
                 mov State,w                ;set continuation address of state after duration is finished
                 mov StateDurLow,#5     ;stay in this state for duration
                 mov StateDurHigh,#0+1  ;needs to be minimum of 1 for dec instruction to time properly
                 jmp Main                      ;wait for next tick

Hope this helps.

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m110982
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\22@234707 by PJMontyn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, PJMonty wrote:

Bebopalot,
The "Literal truncated" message is because the SX uses internal values that are 12 bits, but when it's loaded into W, SASM has to lop off the upper four bits to fit it into an 8 bit register.  It's a warning you can safely ignore.  Adding this line...

               LIST Q=37; This quiets SASM "Literal truncated" warning

... to your code will suppress it.

[list]Thanks,
PeterM[/list]
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m111048
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\23@040331 by javalinn/a
flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, javalin wrote:

PJ,
I notice you're using shadow registers in the ISR to modify the pins.  Is this for a particular reason?  
Relevant code below:

                 mov w,Port                 ;get current state of port bits
                 and w,#%1111_1100     ;clear burst output bits
                 or w,BurstBits               ;merge in the current state of the burst bits
                 mov Port,w                  ;transfer the pre-calculated value for the port to the port
                 mov w,#IntConst          ;load w to interrupt again in 125 clocks..... 2.5 uSec

The reason I ask is that I am having issues with an SX application that reads two 115k serial inputs, buffers it and sends them out.  Essentially a serial relay app.  Periodically I have (i.e. half way through a relay of a CMU2CAM picture) a load of line errors.

I am using currently setb and clrb (based on the dualuart.src senix example) to manipulate the pins.

Cheers for any thoughts!

James
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m111053
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\23@073558 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi James;
The reason I modify the output port pins in the ISR is because I want to effect the required levels at EXACTLY the same instant, every time. If I did it in the mainline, then the timing of those port changes are subject to variations due to other things the mainline is doing. In other words, they are less deterministic.

So, if I pre-calculate what the next output levels are to be in the main line, and then output those at exactly the same spot in the next ISR, we get the transitions happening at exactly the same instant every time. Totally deterministic. When you look at it with a good scope, there is less than 2 nano seconds of jitter.

For precision pulses or frequencies this is required. Although I'm not sure if that level of accuracy is required by Bebop, it's easy to do, so why not?

In your case, if the bits are not set/cleared at the same instant, there could be problems in high speed UARTs.

If you post your total code with a description, I'd be happy to comment. If your code is long or secretive, perhaps you can pare it down, but of course please test the shortened version to confirm it still exhibits the identical problem.

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m111080
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\23@100256 by javalinn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, javalin wrote:

Peter,

Thanks for your offer.    Attached is current version of software, along with example of serial corruption (jpg)

The code is fairly well commented.  The essence of the app is to use the ISR to read serial from two UARTS into two 32byte buffers, the ISR also has a transmitt function.  The mainline then empties the buffer and keeps the ISR transmit going.  Data recieved on one uart is transmitted out of the other, and vice versa.


This is based on the dualuart.src example from Senix and the 16byte buffering from Gunther!


Cheers for your help,

James
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m111136
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\23@133518 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi James;
I think you are correct in your assessment; although I have not attempted to run your code.

Does the problem go away when you run at slower baud rates?  If so, then that is more evidence of your suspicions.

What you are doing in your ISR, is sampling the inputs, and setting the outputs at somewhat indeterminate times (instruction cycle wise) due to the unpredictability of which UART (1 or 2) and which element (transmit or receive) is doing what. And that is an external, unpredictable affair.

You could fix that by sampling the UART inputs into a temporary storage at a fixed point near (at ?) the beginning of your ISR, and also set the UARToutputs from a temporary (shadow) register at a fixed point in your ISR. What is important is the time from entering the ISR and the point where you sample the inputs and set the outputs be always at the same time (hence instruction) reference.

This is most easily accomplished by having no variable instruction paths prior to these events, and that is done with temporary shadow registers.

Other than that, I believe your code can also be "tightened up" by 20% to 40%, and I'd be happy to have a go at that if it's of (significant) interest to you. (I live for the challenge, you see, but do not want to waste my time).

I assume you will always transmit (relay) the received data at the same data rate? In other words 115200 in to 115200 out, and both in 8N1 format.

Please advise.

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m111186
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\23@134920 by javalinn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, javalin wrote:

Hi PJV,
The issue goes away at 57600, even if the camera is running 57600 and the pc 115200.  Its bizzare that the error is always half way down a large picture "download".  Always in a repeatable pattern.  If I get the camera to slow down (I think it delay's between bytes), while still at 115200, the problem also goes away.

www.sxlist.com had some fragmented information on writing to pins at high speed, and using shadow registers - didn't really make total sense I must admit!

Thanks for your offer, but I dont want to waste your time fixing an issue in my code.  However, if you are willing, a short ISR example, with using the register-shadow technique would be enough for me to re-work my code to see if that cures the issue.

I will be relaying at different speeds, i.e. 115 to 19.2, however in short bursts and within the mostly within the buffer sizes.

Appreciate the help so far!!

James
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m111187
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\23@144821 by amillern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, amiller wrote:

This is a classic symptom of accumulating bit rate errors between your two devices.  
Most likely the ISR rate and Oscillator speed are off just enough from the exact serial bitrate that, without breaks between characters to reset bit timing, the two  bit rates get farther and farther out of sync.

At some point, you miss a bit, or you read a bit twice.

Try having the sender put a pause in the data stream, at least at the end of each text line.  The inter-character gap resets the start of character timing, and clears the  accumulating bit-rate timing errors.

The other alternative is to use oscillators that are higher tollerance, or have a frequency that is an exact binary multiple of the desired bitrate.  
To exactly match bitrates, is one reason you see older crystal oscillators with oddly fractional decimal frequencies. 4.096MHz etc.

-AGM-
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=109670#m111189
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\23@145842 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi Andrew;
No, that is not the right way to fix this. Each character (byte) resyncs every time on detecting the start bit, so extra inter-character spaces should not be required.

It IS a requirement of course that the sender transmit at least the number of stop bits that the receiver is expecting; one in this case. After that all should be OK if one samples the bits in a byte consistently at the same, and correct time.

I'm sure we'll get James' issue dispatched with shortly.

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m111190
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\23@155239 by amillern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, amiller wrote:

Peter,
If the stop-bit length is 1/bitrate, as expected, the VP will still accumulate the error.  Basically, the VP can't see the "edge" of the start-bit until after the error-accumulated stop-bit time, pushing the start-bit's "window" further and further out of sync.  
If your receiving VP isn't waiting for the whole stop-bit, then yes, you are correct. That is not the poster's case.  
Most/All of the existing SX UART VP's around just take one sample in the middle of the bit period.  This is simpler/smaller code, and works, until the bit timing accumulates a (bittime/2) error, pushing the sample point past one end (start or finish) of the real bit period.

I once started work on a smarter UART VP, one that looks at several bit samples within a bit's period to determine the sent bit's value.  I abandoned the project when the ISR code grew too long for the project, instead making sure the sender paused between large blocks of data to reset bit timing and re-find the leading edge of the start-bit.

-AGM
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m111196
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\23@174912 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi Andrew;
Still I think you are incorrect....... I like to work on the basis where we do not have control over the sender, and we have to live with whatever we get, provided it's "in-spec".

There is absolutely no problem in sampling only once (in the middle) of each bit, PROVIDED that we "see" the front edge of the start bit sufficiently rapidly. My experience is (and that is considerable) that one can "get away" with 3X over sampling, but 5X is more "comfortable". If one does the latter, there will never be a problem with bit-drift. If one does the former, one is generally OK.

But "generally" isn't good enough, as I like to design things so they ALWAYS work as long as things (timing) are in-spec. So to deal with this, I wrote a VP UART that oversmples 3X, and then also adjusts its synchronization on any transition it sees along the way in receiving the byte. It works, absolutely, 100% of the time.

I'm not suggesting that's what James requires here, as his problem is sampling at inconsistent times. A temporary shadow register will solve that for him, and I guarantee you it will work 100% without messing with the sender.

If the sender is out of spec of course, that's a different story.

By the way James, I don't know if I'll get this done for you tonight........more likely some time this weekend.

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m111204
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\24@023154 by javalinn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, javalin wrote:

Peter,
No worries with time, just grateful for the help.

I see what Andrew means, the behaviour he describes fits exactly with what I see when I test it.  When I recieve a half size picture, or the CMU2CAM sends with some delays in the transmission the issue does not occur.  Slow or infrequent (i.e. me typing commands) data again does not show any issue.

I have a number of 75mhz chips & osc's so I can change it to 4x sampling and see if the issue goes away.  Ideally i'd like to be able to deal with 50mhz and 3x sampling, but if its not possible......

Thanks,
James
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m111242
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\24@082951 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi James;
You get more "mileage" out of your processor's instructions by using an odd number of over sampling. Depending on the accuracy of baud time you select (I frequently use a "nice" number rather than the actual 1/Baud the calculation suggests), an over sampling of 3X works well. If I purposely skew the Baud time to get my "nice" number, I frequently use 5X.

In any case, I'm going to assume you don't have control over the character format (only one stop bit) and the character rate (continuous transmission without interruption) in selecting a good answer for your situation.

Also, from a processor load perspective, do both relay directions always happen simultaneously?

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m111307
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\24@083616 by javalinn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, javalin wrote:

Hi Pjv,
No, the format of the conversation is generally command-then-answer.

I dont have any control over the serial format, its the 8N1 format as usual.  The speed I can slow down (waits between bytes) on this device, but would not like to go that route as I am unlikely to be able to do this on other devices.

If I 5X rather than 4X, surely I get even less time in my already busy ISR to run 2 * 115200 UARTS?

Cheers,
James
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m111312
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\24@090049 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi James;
Clearly so. But in detecting bit edges with certainty,  4X buys you very little over 3X, so you're better off with that odd number, instruction count wise.

That's what I mean by "more mileage" out of you instructions.

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m111322
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\24@151408 by ShadowsSoldiern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, ShadowsSoldier wrote:

Peter I wanted to thank you for your generosity in writing that code. I realize that much of it was geared to instruction and I appreciate that. I am still digesting it in my processor and may have some questions for you at a later date. Basically, that was kick-butt instruction and I think many novice Sxers like myself would benefit from referencing that.

I also wanted to point out that there are many similarities in our approaches. The only time I write to the ports is during the ISR, and it is the same amount of steps during each transmitter burst. So I beleive that my foundation is deterministic. I use flags in my ISR to signal my "non-ISR" time to perform reconfiguration and state loading functions for the next ISR. I thought my ISR reconfigure scenario, it too being state dependent, was fairly clever but I guess it wasn't as cool as I thought it might be. The ISR count triggers reconfiguration of the ISR frequency ... What I was impressed with in your code was the use of faster processing speed and higher bit counters, which like I said earlier, I am still trying to understand.


Are there any other conceptual differences between the two approaches that I am missing?


Thanks Peter

BBAL
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m111422
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\24@151525 by ShadowsSoldiern/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, ShadowsSoldier wrote:

Peter I wanted to thank you for your generosity in writing that code. I realize that much of it was geared to instruction and I appreciate that. I am still digesting it in my processor and may have some questions for you at a later date. Basically, that was kick-butt instruction and I think many novice Sxers like myself would benefit from referencing that.

I also wanted to point out that there are many similarities in our approaches. The only time I write to the ports is during the ISR, and it is the same amount of steps during each transmitter burst. So I beleive that my foundation is deterministic. I use flags in my ISR to signal my "non-ISR" time to perform reconfiguration and state loading functions for the next ISR. I thought my ISR reconfigure scenario, it too being state dependent, was fairly clever but I guess it wasn't as cool as I thought it might be. The ISR count triggers reconfiguration of the ISR frequency ... What I was impressed with in your code was the use of faster processing speed and higher bit counters, which like I said earlier, I am still trying to understand.

Are there any other conceptual differences between the two approaches that I am missing?

Thanks Peter
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m111423
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\26@213527 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi James;
This thread has gone a bit off topic, so I'm posting a new DUAL UART RELAY thread to deal with your need.

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m111894
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\27@113423 by mrchadwickusan/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, mrchadwickusa wrote:

Hi All,
Just to throw in my 2 cents, as I didn't see this potential problem mentioned anywhwere.  In the case where you are receiving at 57600 and sending at 115200, you have no problem.  Which makes me suspect that what is causing your error at 115200 in and 115200 out is a buffer overflow.

If the output baud rate is just slightly slower than the input baudrate, at some point you will get out of sync between your output and input, and your 32 byte fifo will start to fill up.  After a while you will fill the fifo and lose a character.

You might want to add code to test the fifo level and see if it has overflowed.  From the sound of it, this occurs about halfway through the picture.

This might seem counter intuitive, but it only takes a fraction of a bit of baud rate error to cause this problem, it is a result of the aggregate data rate in bytes per second being slower on output than on input.

If your output baud rate is slower by even 1 %, after 10 characters you will be one bit behind the input.  After 100 characters you will be one whole character behind. (assuming 10 bits per character) This is not a problem for short enough packet lengths because your fifo accumulates the excess incomming characters. Eventually the fifo overflows and you lose a character.

An alternative test would be to adjust your ISR to be just a little faster than 115200, and see if the problem goes away.  Anything up to 2-3% will generally not cause a problem if your receiving serial port on the PC end is not more than 2-3% off also.

---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m112020
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\27@130624 by javalinn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, javalin wrote:

Michael,
Spot on!

I added a quick test and an LED to see if this was the case.  Soon as the LED came on the image corruption occurred.

Cannot believe didn't catch this before!  I was very puzzled that it worked for a while (aka it must be working) then showed the error.

Cheers for your help - I've been going arround in circles (fifo obviously) for ages....

James
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m112054
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\27@131946 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi Michael;
You are absolutely correct PROVIDED the UART receiver waits for the whole stop bit before it is permitted to receive again. This could not typically be the case as then ALL continuous transmissions could never be received if the receive clock were fractionally slower than the transmit clock.

Although I have no definitive specifications, I suspect that all (most) UART receivers will (must) permit reception of a new start bit some time after the passing of only a portion (half?) of the stop bit.

This then will permit some small level of transmit and receive clock discreptancies as one would expect.

In other words, each start bit re-syncs the reception sample clock, hence small errors in clocks are not cumulative beyond single characters. Inside a single character, of course cumulative clock errors must be dealt with, and that is typically achieved by having sufficiently accurate clocks.

Therefore, I believe James' problem is not one of buffer overflow, at least not due to slight clock discreptancies. Possibly he could see a buffer overflow if any inadequate flow control was involved.....and we don't know this.

In looking at his posted code though one can see that due to unpredictable timing of events (transmission and reception), varying jump-routes in his transmitter's bit transitions and receiver's sampler are occurring at significantly consistent times in his ISR, therefore causing jitter in his clocks.....exactly what we don't want in a high speed situation. So my belief is that curing this effective clock variation will solve the problem, and that could be effected with using a shadow register transfer in the ISR.

This solution is not 100% guaranteed however, as the problem could also be just running out of instructions in the occasional long ISR, throwing the consecutive interrupts off, and hence a "blip" in the data validity.

My bet is that the deterministic UARTs I wrote for him will solve the problem, albeit there is not a lot of execution cycles left (but I believe enough) when running at full tilt. An actual test can best verify this as I did not have access to the actual harware and operational circumstances.

On the other hand, I could be all wet................in any case, do enjoy the VP UARTs I wrote.

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m112057
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\28@130918 by mrchadwickusan/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, mrchadwickusa wrote:

Hi PJV,
Actually it doesn't matter if the receiver waits for the stop or not, even though it re-syncs to the start bit every character there will still be a problem if the input characters come in faster than they can be sent out.

Think about it this way, if the length of time between input characters from start bit to start bit is 100 microseconds, and because your output clock isn't quite as fast, it takes 101 microseconds to do the output character, eventually you will accumulate more input than you have been able to output.  The fifo takes up the excess, but eventually runs out of room, because in aggregate you are sending bits slower than you are receiving them.

The thing about this kind of problem is that it is subtle.  If you try to do a test by sending to your self, it will *always* work, because your bit rates are *exactly* the same.  The problem will only show up if your output rate is slower than your input rate.  In a gross example think about what would happen if you were receiving at 115200 baud and sending at 57600 baud.  Even though you receive each input character correctly, very shortly you would run out of space in the fifo and characters would be lost.

I've been bitten by such situations before :)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m112282
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\28@173723 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi Michael;
You are correct........... IF the basis of analysis is: "if it comes in faster than it goes out" then the buffer will fill up.

But that was exactly my point.

By "cheating" a little in receiving the stop bit, and buffering it a little early (that is before the reception of the stop bit has completely finished), then we are gaining a little time for the re-transmitter, and it can start sending before the reception is completely finished. Now it has ample time to get the received data in the buffer back out, and the buffer will empty instead of fill.

The UART I wrote and described does this, and that, I believe, is the salient point in all this.

We are assuming here of course that the discreptancies between the UART clocks is small.

Please show me where I'm wrong in this assessment........

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m112335
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\02\28@235936 by mrchadwickusan/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, mrchadwickusa wrote:

Hi Peter,
I think you are missing the forest for the trees, or the characters for the bits, in this case.  The issue is the total time it takes for an input character versus the total time for an output character.  If the input baud rate is exactly 115200 baud, and we have 8 data, a start bit and a stop bit, the input character will take 10/115200 or 86.8055 micro seconds.  If the output baud rate is 115000 baud (a .17 % difference) the output character will take 10/115000 or 86.9565 micro seconds, pretty close to 150 nanoseconds longer for output than input.  That means that after 86.8055/.150 or 579 characters, the output will be one whole character behind the input.

Every 579 characters the fifo will accumulate another character so that after about 16 kbytes of data, a 32 byte fifo will fill up.  At that point, after another 579 characters, the output will be 33 characters behind and the fifo overflows.

"Cheating" on receiving the stop bit would gain half a stop bit on the *first* character only.  It still takes 10 bits worth of time to send the character.  If the input bits are faster than the output bits, data will accumulate before it can be sent.

Another way to look at it is by characters per second.  In the 115200 baud case it would be 115200/10 or 11520 characters per second, at 115000 baud it would be 11500 cps.  So we are getting characters sent to us at 11,520 cps but we can only send at 11,500 cps.  Every second worth of continuous data we will get 20 characters behind.  Once the fifo fills up with the accumulated backlog, you lose characters.

Suppose you start sending the first character of a message out as soon as the last data bit is received, we will postulate that is halfway into the last data bit, because we are perfectly in sync with the input start bit.  We have one and a half bits before the next character comes in.  In a perfect world, with identical input and output baud rates, the first output character would just finish being sent at the halfway point of the second input character's last data bit, and the process would continue without problem.

If your output baud rate is just a little slower than the input baud rate, then that first output character doesn't get done until a little past the middle of the second input character's last data bit.  Each subsequent output character will finish a little later than the previous one, until eventually you are behind by a whole character.  At this point the fifo always will have one character in it, at all times.  As time goes on, it gets further and further behind.  This issue comes up if the input data rate is any amount faster than the output data rate.  Before the first output character is done, even by a fraction of a bit, the second character is received and must go into the fifo because the transmitter is still busy outputting the last .01% (or some fraction) of the stop bit.  This causes the output characters to gradually slip in time compared to the input characters.

Eventually you fill the fifo, even though you are transmitting as fast as you can, because the input data rate is ever so slightly faster than your output data rate.

---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m112387
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)


'[SX] IRC is a few cycles short'
2006\03\01@084036 by Peter Van der Zeen/a
flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi Michael;
Sorry, but I can't agree with your logic.

Let's say the UART receive clock and the re-transmit clock are identical, and also happen to be the same as the "foreign" data stream we are receiving. Also let's say that the continuous incoming stream and the receiving UART bit edges are aligned, and the re-transmitter is waiting for a byte in the buffer.

Now, as you say, let the receiving UART transfer the first character being received to the buffer at the instant the sample of the 8th data bit is taken, say in the middle of the bit. This leaves us with the balance of that bit plus the stop bit before the second character's start bit will fall.

So the re-rtansmitter senses the first character in the buffer, and will start its re-transmission of that first character at the same instant. That means we are starting the re-transmission of character one's start bit before we have received the "trailing end" of the first incoming character.

Now, if the baud clock of the re-transmitter were just a bit slow, then it would finish sending the first character a little later than the middle of the 8th data bit of the second character in the input stream, but still well before the start edge of the third character. So this has the EFFECT of making the re-transmit appear faster than the receive stream, and hence there is no "bunching up", or clock creep in the system. There is 1.5 bits of "slop" time available for the re-transmitter to "gow" into for every received charcter.

This should work perfectly for re-transmit clocks that are up to 1.5 bits "slow" over one character under ideal cases. In reality one needs to expect a little less because clock edges are not normally ideally aligned, and one cannot be sure exactly when receive samples are taken in any bit.

If you still feel my analysis is wrong, (and I feel I'm right) then I will spend the time to set up three independent UARTs to prove (or disprove) my position.

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m112452
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\03\01@215923 by mrchadwickusan/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, mrchadwickusa wrote:

Hi Peter,

I think the proof is the fact that Javalin did the test and the fifo overflows just when the error happens!


I see from what you wrote above, that you are postulating that the receive clock and the transmit clock are *exactly* the same as the incoming data clock.  Well, that isn't the case.  The foreign data is faster, by some fraction, than the clock the SX is using to control the transmit of each bit.


Internal to the SX the clock for receiving data and sending data is the same.  It has to be unless you went to great trouble to do otherwise.  But that isn't the same as being exactly the same clock rate that the PC used to send the characters the SX is receiving.  That clock is almost surely different in speed to the SX interrupt rate, which is our receive and transmit clock for the SX.


I think you are interpreting the received clock to be the SX ISR clock used to sync to the incoming data.  That isn't what I was saying.  What I'm saying is that the data we receive is clocked at 115200 but the data we send is clocked at 115000.  That mismatch will have no effect on receiving individual characters (which we do with the 115000 baud clock), but the aggregate data rates being different, will cause the fifo to fill.  There is no way around that!  The whole point of having a fifo is to accommodate mis-matched data rates. Yes each character will be synchronized by it's start bit, but it still takes less time to come in than it takes for us to send it out.


The received data rate, as transmitted from the PC is faster than the outgoing data rate from the SX.   It doesn't matter how soon you transmit the characters relative to receiving input from the PC; you still take 10 bit times per character at whatever your transmit clock rate is.  If the outgoing bit time is longer than the PC's transmitted bit time (what we received), you will fill the fifo and lose characters when it is completely filled.


I think it would be good to try such a test setup, but make sure your SX's data clock is just a little slower than the input data source's clock.  Your fifo will fill up eventually, unless you have pauses between your incoming characters.


Another way to think about it that might make it clear would be to do the following:  Draw a one inch line on some 10 square per inch graph paper.  Call the 1 inch the character from the PC.  Continue for some number of characters, putting a tick mark to indicate the boundaries of the characters, each character being 10 squares long.  Below that line, starting 1.5 squares before the end of the first character, draw another line 10.5 squares long and repeat to simulate a slower outgoing bit rate than the incoming bit rate.  Very quickly the start of your output characters will move past the start of the input characters and at that point the fifo will fill by one, and never catch up. Unless there is a pause in the input data.


Yet another way to think about the fifo and mismatched input and output data rates would be to picture a can with a small hole in the bottom.  Take a second larger can with a bigger hole in the bottom.  Hold it over the first can, and fill it with water so that water comes out of the big hole and goes into the first can with the smaller hole.  The bottom can will start to fill up, until the top can runs out of water.  If the top can is much bigger than the bottom can and holds enough water, the can with the smaller hole will overflow.


I will try to illustrate here with what I think is a fixed size font:


Each input character is 10 Is, each output character is 11 Os. The first output starts halfway through the stop bit of the first received character. I used a ! to indicate the border between characters.  The ^ is used to indicate when the input character has been completely received and ready to be transmitted.


IIIIIIIIII!IIIIIIIIII!IIIIIIIIII!IIIIIIIIII!IIIIIIIIII!IIIIIIIIII!
        OOOOOOOOOOO!OOOOOOOOOOO!OOOOOOOOOOO!OOOOOOOOOOO!OOOOOOOOOOO!
        ^ first in ^ 2nd just ^ 3rd must ^  fourth must
          is sent    makes it   wait for    wait for third
        immediately  without    2nd out     to finish
                     having     to finish   so goes into
                     to wait    so goes     fifo until
                                into fifo   transmitter
                                until       done with 3rd
                                transmitter
                                done with
                                2nd
 
Notice how quickly the output starts to slip behind the input! This is a gross mismatch, but exactly the same thing happens with a small mismatch. The output character takes longer to send than the input character did to be received, and so the output gets further and further behind.


Another analogy is an escalator, the speed of the hand rail never matches the speed of the stairs, so your hand either starts to go ahead of you or behind you.


The easy solution for Javalin is to make sure his SX is outputting bits faster than the PC is sending them.  In that case the fifo will never fill at all. It would at most have 1 character in it at a time.


That would be like this where I use 11 Is to be input and 10 Os for output. Again the ! is the border between characters, and the ^ indicates when a character is fully received and available to be sent.


IIIIIIIIIII!IIIIIIIIIII!IIIIIIIIIII!IIIIIIIIIII!IIIIIIIIIII!
         OOOOOOOOOO! OOOOOOOOOO! OOOOOOOOOO! OOOOOOOOOO!

         ^           ^           ^           ^  
The output character takes less time to send it's 10 bits than the input character, so there is no problem keeping up. In this case the transmitter is always done before the next input character is done.


For 50Mhz clock at 3x 115,200 baud the ISR count would be 144.67 cycles.  If we round up to 145 cycles the real ISR rate will be 114,942 which almost guarantees the fifo will fill.  If we round down to 144 cycles we get 115740 which should guarantee the fifo never fills, unless the PC transmit clock is faster still. In the first case we are .2% too slow, in the second we are .4% too high, but being too high is the preferable way to err in this situation where we have continuous input to process and then to output.  

Any pause in the input before the fifo fills up will also prevent the problem, but having a pause in input doesn't seem to be an option here.

---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m112607
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\03\02@081102 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi Michael;
Well, we are still on opposite sides, and I will do the tests.

Sure, I acknowledge that the buffer fills up, because that was proven it a test. But the REASON it fills up is now the issue.

Yes, I fully understand that the receive UART and re-transmit UART are working form the same clock, and hence there is no "slip" between them.

In postulating all clocks were the same, that was simply a reference point for determining timings.

My point was, said in another way, is that the software UARTs I designed dealt with received data before the end of the complete character, and THAT is what provides the "extra" time to permit the receiver/retransmitter pair's clock to be a little slower than the foreign clock.

I hope to get to this in the next several days, so please stand by......

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m112663
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\03\02@085513 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hello Michael;
I did something like the timing diagram you suggested, and found indeed you are correct!

In my example, I show two half-clocks per bit; SS is "start", 11 through 88 are the "data" bits 1 through 8, and PP is the "stop" bit.




Foreign data stream SS1122334455667788PPSS1122334455667788PPSS1122334455667788PPSS1122334455667788PPSS1122334455667788PP
Receiving UART                          SS112233445566778...SS112233445566778...SS112233445566778...SS112233445566778...

Retransmit UART                                          SS1122334455667788PPSS1122334455667788PPSS1122334455667788PP


So, I can now see that regardless of when the re-transmitter starts sending, it always needs to transmit 10 bits per character continuously, and if the foreign stream is also continuous at a slightly faster clock rate, the re-transmitter eventually can't get rid of it in time, and data corruption results.

So what this implies is that one can never reliably "repeat" data at the same rate as it comes in without shortening up the repeated stop bit......


Sorry to have been such a pain about this, I was totally convinced of my position. Now I know better.....I learned several things today!


Cheers,

Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m112677
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\03\03@023852 by javalinn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, javalin wrote:

Hi Michael,
Good explaination; I'm planning to use some of PJV's dual uart code to tighten-up my buffering code.

I will also now be experimenting with the ISR timing to overcome the re-transmiting issues.

Interesting......

James
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m112835
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\03\03@094454 by javalinn/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, javalin wrote:

Michael & pjv,
I have just tried reducing my ISR RETIW value from 74 to 73 and it works!

Cannot believe the fix is *so simple* !!

Cheers for your help!

James
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m112903
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\03\04@103423 by mrchadwickusan/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, mrchadwickusa wrote:

Hi Peter and James,
Peter, I guess we are both stubborn intelligent people!

I just took the time to look over your dual UART code, and I think it is very clever.  I see a couple of conceptual things I'm going to try to apply to some UART and buffer macros I wrote.  
The macros use only 2 bytes of ram plus the buffer space for each receiver and transmitter.  Because of that they are a little slow as there are a number of bit manipulations to keep pointers etc within those 2 bytes of overhead. I think I may be able to change them to use the state machine concept to reduce their execution time, fewer tests of counters etc.  For sure I can use Peter's concept of setting the receiver shift register to determine that 8 bits have been shifted by setting the carry on the last shift.  I think that is a brilliant case of killing two birds with one stone!

Using the shadow IO register in a very short ISR with state machines in the main loop to keep the bit timing in and out rock steady is a very powerful concept.  I have used a similar scheme for non timing critical things like blinking a led, but never for something like serial communications.

The only down side I see to using the state machine concept for timing critical items, is that all functions would have to be coded in such a way as to ensure the main loop gets back to the start before the next ISR happens.  If you had an operation that takes more time than available, you would have to make it a state machine and split it up into chunks that can be executed in less than the time until the next ISR.

Of course you could turn the concept upside down in the classic virtual peripheral way, still using the shadow register at the start of the ISR, but have the ISR execute all the required time critical state machines after the I/O.  Then any time consuming tasks in the main loop get whatever is left after the ISR completes until the next ISR.

James,
I'm pleased to see the that the fix was as simple as I thought.  Good luck with the rest of your project!

---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m113173
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

2006\03\04@142145 by Peter Van der Zeen/a

flavicon
face
In SX Microcontrollers, SX/B Compiler and SX-Key Tool, Peter Van der Zee wrote:

Hi Michael;
You know, I'm only stubborn when I think I'm right, and in this case I was in error. So, please excuse me.

Regarding state machines, sure, in some cases the state needs to conclude before the next ISR fires, and the writer needs to be aware that this may require some co-operation between routines.

When I have a bunch of independent yet timing critical things to do, I use my pre-emptive RTOS, and now I can write code at will without (much) regard for timing relationships. The're all independent, so a long task may be pe-empted by a more frequently running task.

Quite amazing how well it works. Only 99 bytes of code, but, unfortunately, quite a bit of RAM to save the thread states if all 8 threads are implemented.

Cheers,
Peter (pjv)
---------- End of Message ----------

You can view the post on-line at:
http://forums.parallax.com/forums/default.aspx?f=7&p=2&m=109670#m113210
Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com
The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)

More... (looser matching)
- Last day of these posts
- In 2006 , 2007 only
- Today
- New search...