Shop OBEX P1 Docs P2 Docs Learn Events
SERIN & Flow Control Strategery — Parallax Forums

SERIN & Flow Control Strategery

PJAllenPJAllen BannedPosts: 5,065
edited 2008-08-07 16:29 in General Discussion
· I want to receive data via SERIN and stash those bytes into an I2C EEPROM, on-the-fly.· I·can accomplish·this in hunk-and-peck·fashion, with or without flow control,·but I fall short sending several bytes in succession.· I'm trying to send this data out as a text file.·
· The I2C writing operation takes·'a lot' of·time and·to accomodate that I need to signal DTE that the SX is busy.· So, I thought that I'd try setting a pin as "CTS" output.· This got me a little further than having no flow control at all, but not by much.
· I'm only going 1200bps, so I figured that with 28_000_000Hz I could zip off the CTS in time, but it looks like it gets tangled up anyway.· I suspect that "CTS" doesn't drop fast enough.

· Is there an internal counter that could be monitored and used to de-activate "CTS" when the Stop Bit starts?· ·

· [noparse][[/noparse] I'm using a MAX232, my states are correct. ]

  FOR addr = 1 TO 72
    CTS = 0                              ' CTS active
    SERIN serial, T1200, outByte
    CTS = 1                              ' CTS inactive
    EEWrite addr_LSB, addr_MSB, outByte
    NEXT

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-08-04 06:27
    Most PCs have several characters of latency when they transmit using flow control, so you will need to provide a small RAM buffer to catch them before writing to EEPROM. I'm not sure how to accomplish this in SX/B; but in assembly, you'd write an interrupt routine to read and buffer the characters. My rule of thumb is to deassert CTS when the buffer is 3/4 full and reassert when 1/2 empty. Then your write-to-EEPROM routine could run in the foreground, dequeuing characters from the buffer at its leisure.

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-08-04 14:29
    I've attached a bit of code that uses buffered serial IO with CTS handling the way Phil describes above.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2008-08-05 02:12

    I've been looking at the Assembly generated by SX/B:

    MOV FSR,#__TRISC     ;    SERIN RC.7, T1200, outByte
    MODE $0F                      
    SETB IND.7                    
    MOV !RC,IND                   
    BANK $00                      
    JNB RC.7,@$                   
    JB RC.7,@$    
    [color=red][i]CLRB RC.4[/i][/color]              [color=red]' CTS active  ??[/color]
    MOV __PARAM2,#8               
    MOV __PARAM3,#10              
    MOV __PARAM4,#20              
    DJNZ __PARAM4,@$              
    DJNZ __PARAM3,@$-3            
    NOP                           
    NOP                           
    MOV __PARAM3,#19              
    MOV __PARAM4,#39              
    DJNZ __PARAM4,@$              
    DJNZ __PARAM3,@$-3            
    JMP @$+2                      
    RR __PARAM1                   
    MOVB __PARAM1.7,RC.7          
    DJNZ __PARAM2,@$-17  
    [color=#ff0000][i]SETB RC.4[/i]             ' CTS drop now  ??[/color]         
    MOV outByte,__PARAM1  [color=red]' I guess this is where data XFERs to [/color]
    [color=#ff0000]                      ' outByte[/color]
    

    I see that CLRB RC.4 is ASM for RC.4 = 0 and SETB RC.4 is ASM for RC.4 = 1.· Where would be the best places for them if they set/drop the CTS output?· Which ASM line detects the start bit·and which assumes the stop bit?
  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-08-05 04:26
    The line

    JB RC.7, @$

    ... is what is waiting on the start bit; the stop bit is ignored and the program moves the work value in __PARAM1 to the output during the stop bit timing (I think the purpose of stop bits is to give the receiver time to do something with the byte it just received).
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2008-08-05 12:25
    OK.· JB RC.7, @$

    I'll·see how·making CTS active immediately before that goes, keeping the CTS drop-out where I placed it in my preceding.
    Maybe I'm asking too much of RTS/CTS by trying to get DTE to stop&go like this (haltingly.)

    [color=black]...[/color]
     
    JNB RC.7,@$ 
    [i][color=#ff0000]CLRB RC.4[/color][/i]              [color=red]' CTS active[/color]                  
    JB RC.7,@$    
    MOV __PARAM2,#8 
     
    [color=black]...[/color]
     
    DJNZ __PARAM2,@$-17   [color=#ff0000][i]SETB RC.4[/i]             [/color] [color=#ff0000]' drop CTS[/color]
    MOV outByte,__PARAM1 
    
    
  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-08-05 14:12
    Yes, I think you are. Can you use the ISR-driven code I posted earlier? It gives you an eight-byte buffer and the ability to control CTS before the buffer has a chance to be overrun.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2008-08-05 23:02
    I am not INTERRUPT-savvy.· It's a gaping hole in my skill set.· I'd want to pare it down to receive-only.

    Can I have the program·go with·the data-input/UART as an INTERRUPT-based routine at the beginning and then drop into a non-INTERRUPT operation?

    I'm a little surprised that it's being so finicky at 1200bps.· It fills up VAR arrays·like crazy, but introducing the flow control as a break in order to transfer the RX'd data into an I2C gums up the works.· SimpleTerm may be real tight on stop-bit time/s (no "stop-bit and a half.")
  • CounterRotatingPropsCounterRotatingProps Posts: 1,132
    edited 2008-08-06 01:56
    Jumping in here to ask a related question as I've been trying to glean from various posts what the actual bandwidth (or external chip communication "loading") is for the SX'es. (Still hunting the posts and archives to see where this was discussed before.)

    What would happen if PJ were to use his original code, with or without a small buffer, but use an SX 48 running at 75 mHz - without Interrupts? Would the handshaking perform better / correctly?

    PJ, doing interrupts is pretty easy actually (until you have to deal with timing issues :-| There's plenty of post and sample code. Check out some of the NV articles... it's well worth learning 'cause you can do such cool stuff with it. Actually, the background buffering of serial data streams was one of the earliest uses of interupts!

    cheers,
    Howard in Florida
    PS. the level of mutual support here is incredible! Thanks all very much...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Buzz Whirr Click Repeat
  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-08-06 02:12
    You wouldn't want to selectively turn the interrupt on and off, and only a few instructions would be affected by using the interrupt. I'm actually designing a new product now that uses a serial port to transfer the contents of a 64K EEPROM to/from the PC. The great thing about I2C is that it's synchronous and therefore not affected by the ISR.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2008-08-06 02:24

    · I don't need an SX48 to run a faster crystal/osc.· I have a 50Mc osc which I may pull out.· Maybe I could hit it with more speed.· I don't know.· Maybe I could modify the ASM for 300bps.

    · Anyway, I think I'm going at a pretty good clip right now, but I'm missing every other character with my present program.·
    · (My terminal program has a modified setting, "Data Send Block Size 1 -- Best response to flow control, slow data transfer rate")·
    · At 1200bps, a bit is 833usec.· However long it takes for CLRB to execute (my big assumption) can't be a meaningful fraction of that 833, it should nail it.· Maybe I can place my drop CTS earlier.
    · I only have a Blitz and, so, I program the SX, reconfigure and send data, pull the eeprom and read that with a eprom programmer.
    · Fun, fun, fun.

    ASM
      MOV FSR,#__TRISC
      MODE $0F                      
      SETB IND.7                    
      MOV !RC,IND                   
      BANK $00                      
      JNB RC.7,@$
      [color=red]CLRB RC.4             ' CTS ON[/color]
      JB RC.7,@$            ' get start bit        
      MOV __PARAM2,#8               
      MOV __PARAM3,#10              
      MOV __PARAM4,#20              
      DJNZ __PARAM4,@$              
      DJNZ __PARAM3,@$-3            
      NOP                           
      NOP                           
      MOV __PARAM3,#19              
      MOV __PARAM4,#39              
      DJNZ __PARAM4,@$              
      DJNZ __PARAM3,@$-3            
      JMP @$+2                      
      RR __PARAM1                   
      MOVB __PARAM1.7,RC.7          
      DJNZ __PARAM2,@$-17
      [color=red]SETB RC.4             ' CTS OFF[/color]
      MOV outByte,__PARAM1
    ENDASM
    


    CRP,
    · Hey, your avatar -- that's the apparatus Spock·was making·on "The City on the Edge of Forever."
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2008-08-06 02:27
    JonnyMac, your Reply showed up while I was composing my previous.

    There's more to this than the serial-EEPROM trip, so there would be timing considerations later, I'm sure.
  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-08-06 03:02
    Like?...

    In the end, I don't think you're going to get what you want attempting to crowbar CTS control into an inline SERIN.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-08-06 04:17
    I agree with you, Jon. The PC won't stop sending on a dime. Once you tell it to go, it's gonna spew several characters from its FIFO before it even recognizes the next CTS off.

    PJ, it's not impossible to do what you want without interrupts; but, trust me, it's a whole lot easier if you use them. Just think of it as part of your growth as a programmer. smile.gif

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • ZootZoot Posts: 2,227
    edited 2008-08-06 05:11
    Somebody said...
    There's more to this than the serial-EEPROM trip, so there would be timing considerations later, I'm sure.

    You can have a 16 byte (or even 32 byte = 1 page on an EEPROM ) buffer if you take the plunge into interrupts (w SX/B and the many examples of serial ISR ASM routines at the forums it's not too hard). The high-level SX/B commands that are affected if you use an ISR are the internally time-dependent code structures, e.g. PAUSE, PAUSEUS, SERIN/SEROUT, PULSIN/PULSOUT, FREQOUT. Any commands that are clocked are unaffected (even if in an interrupt happens in the middle of a SHIFTIN or I2CRECV, it just means the clock pulse might be slightly longer/shorter).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2008-08-06 12:16
    If it won't stop sending on a dime then what's the use of CTS/RTS anyway?· Maybe there's an implied minimum buffer standard that goes with that (I do not know.)·

    I'm not attempting to crowbar...·I'm attempting to shoe-horn... it's different.· smile.gif

    Too much fun.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-08-06 19:02
    PJ,

    As an alternative, could you come up with some sort of foreground protocol where the PC will only send a character at a time as the SX system asks for it via a serial command? I've used such arrangements with BASIC Stamps, which don't have background capability, and they work reliably. You could still use CTS if you want, except that the PC program would read it as a bit input and send one character, wait for CTS to go low, then high, send another character, etc.

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2008-08-07 00:57
    No, PhiPi, I've got even less going on in that regard than I do in SX-ville.· My term program has what seems to be a staggerred output feature (long pause between bytes), but it may not be all that.

    If anybody could help explain this a bit,
    Given:
        ASM
          MOV FSR,#__TRISC
          MODE $0F                      
          SETB IND.7                    
          MOV !RC,IND                   
          BANK $00                     
          JNB RC.7,@$                   
          JB RC.7,@$                    
          MOV __PARAM2,#8               
          MOV __PARAM3,#2               
          MOV __PARAM4,#76              
          DJNZ __PARAM4,@$              
          DJNZ __PARAM3,@$-3            
          NOP                           
          NOP                           
          MOV __PARAM3,#3               
          MOV __PARAM4,#151             
          DJNZ __PARAM4,@$              
          DJNZ __PARAM3,@$-3            
          JMP @$+2                      
          RR __PARAM1    
          MOVB __PARAM1.7,RC.7          
         [color=red] DJNZ __PARAM2,@$-17[/color]  
          MOV outbyte,__PARAM1          
        ENDASM
    

    Does the -17 in DJNZ __PARAM2,@$-17 mean that it jumps back 17 program lines?· Where is it jumping to, BANK $00?
    ·
  • pjvpjv Posts: 1,903
    edited 2008-08-07 04:26
    Hi PJ;

    Here's the interpretation:

    ASM
    MOV FSR,#__TRISC ;point to the (shadow) memory location that holds the direction register for port C... located in bank F on an SX28
    MODE $0F ;set the MODE to accept changes to the SX direction reggisters
    SETB IND.7 ;prep bit 7 of the shadow register to input direction
    MOV !RC,IND ;now transfer the shadow to the actual direction register inside the SX
    BANK $00 ;return to the default bank
    JNB RC.7,@$ ;loop here, continually testing the serial line for a a low, indicating no transmitter is connected
    JB RC.7,@$ ;loop here continually testing for a high, indicating a transmitter is connected, and in the serial STOP condition
    MOV __PARAM2,#8 ;a low now indicates a falling start bit edge has been detected, set the bit counter to 8 bits
    MOV __PARAM3,#2 ;now load the some parameters to do some time loops (duration depending on baud rates)
    MOV __PARAM4,#76 ; to sample the second bit (first data bit after the START bit) at its mid point..... one and one half bit lengths
    DJNZ __PARAM4,@$ ;and do the timing here
    DJNZ __PARAM3,@$-3 ; with two nested loops.... outer loop is 2 times the inner loop of 76, each of 5 instruction cycles (jump instruction itself is 3 cycles plus the @ page insruction plus the dec-skip-if zero)
    NOP ;some fine tuning of the timing
    NOP ;to get the sampling interval just right
    MOV __PARAM3,#3 ;now load the parameters for timing duration to sample all following bits in their middle; relative to the middle of the first data bit ...... one bit length
    MOV __PARAM4,#151 ;outer loop is 3 times the inner loop of 151 loops of 5 instruction cycles each
    DJNZ __PARAM4,@$ ;and execute the delay here with
    DJNZ __PARAM3,@$-3 ; again two nested loops
    JMP @$+2 ;this is a little weird but is just a 4 instruction time delay... effectively not really a jump in program sequence
    RR __PARAM1 ;move the shifter along one bit and make room for the new bit coming in
    MOVB __PARAM1.7,RC.7 ;merge the sampled bit into position 7 of the shifter.... the previous value is overwitten
    DJNZ __PARAM2,@$-17 ;decrement the bit counter, and if it is not zero (indicating it has done 8 bits) jump back 17 to load up the second set of delay loops again to sample in the middle of the next bit
    MOV outbyte,__PARAM1 ;copy the received result to the destination variable
    ENDASM


    PJ... the $ indicates the present value of the program counter, and the $+ or $- values are relative to that point. The $-17 you referred to is actually 17 instructions... that is program LOCATIONS. The assembled code DJNZ are compound instructions consuming 2 bytes each, and then there is the @ page instruction on top of that. So, no, it does not point back to the BANK which is 17 LINES back, but instead it points 17 SINGLE INSTRUCTIONS back to the load of the timing parameters.

    Hope that helps.

    Cheers,

    Peter (pjv)
  • ZootZoot Posts: 2,227
    edited 2008-08-07 16:18
    Somebody said...
    but instead it points 17 SINGLE INSTRUCTIONS back to the load of the timing parameters.

    PJ -- if you view the "list" output of a compiled SX/B or src program, you will see the hex addresses for actual line instructions on the left. This can be useful if you are trying to deconstruct the assembly of high level commands, esp. in the case of "compound" assembly commands like DJNZ, which expand to much more than a single instruction line. Also, the SX-Key reference has a nice little summary of assembly commands organized by single-word and multiple-word instructions (a "word" in this case being a single instruction).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
  • CounterRotatingPropsCounterRotatingProps Posts: 1,132
    edited 2008-08-07 16:29
    THREAD_INTERRUPT

    > CRP,
    > Hey, your avatar -- that's the apparatus Spock·was making·on "The City on the Edge of Forever."

    PJ, yes - that's my favorite scene of all Star Trek... oh, it's probably copyrighted material, but for educational purposes, it's ok to use. Educational as in "here's what not to do when controlling vaccuum tube circuits with sophisticated microcontrollers."

    ; --- end disclaimer ---

    IRET



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Buzz Whirr Click Repeat
Sign In or Register to comment.