Changing Baud rates using "fullDuplexSerial4port.spin"?

Hi All,
I have a project where I am using a propeller processor (with serial buffer IC's) to intercept data from one serial port, filter that data in real time (blocks some commands & acts on others, inserts some extra data from the other serial ports / i2c ports as required) and then sends the data out on another port.

This is working fine in both directions using "fullDuplexSerial4port.spin" and separate COGs for the send and receive data paths.
I am using SPIN for all functions & so far and it is working well.

So now for the challenge.

Both the input & output ports use the same baud rate, but the source baud rate can be changed by one of these commands I am intercepting, so I need to be able to alter my baud rate in response to a command to do so.

To do this, I think I would follow a process like this:-
(1) Stop the Serial driver;
(2) Change the SysBaud variable (this is the variable for just these 2 ports, the other 2 are fixed at 9600);
(3) re-start the start_uarts routine
S4P.Stop	         ' stop 4 port serial driver (SysBaud must contain new system baud rate by now)
start_uarts              ' re-initialise the UARTs

My question is, Have I missed something simpler?
Is there a way of just changing the 2 baud rates concerned without shutting down the "fullDuplexSerial4port" driver and re-initializing it?
I can't think how but I am fairly new to SPIN and the propeller so could easily be missing something obvious.

My thanks for any comments on this topic

Comments

  • 21 Comments sorted by Date Added Votes
  • You can do this on the fly if you take FDS, strip it down to send only and receive only (if you like), and then put a command parser into the receive PASM routine to change baud rate on the fly rather than stop/start. If your command sequence is not more than 4 bytes long you can maintain a simple long in PASM that accumulates each byte as shift left 8 than add each and every byte. The command parser is then simply a matter of masking if less than 4 characters and comparing to a 32-bit "command". Quick and easy.
    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • Hi Peter, How things in Brisbane, we had some Brisbane type temperatures here in England last week (up to 32'c) but it is back to normal now.
    Thanks for your reply, I can sort of understand what you are saying but have no idea how to do it.
    I have only been using the Propeller chip for a few months and am still getting a grip on SPIN, though I am finding it fairly easy to follow.
    I looked through the "fullDuplexSerial4port" source code but the only references to the baud rate that was obvious to me in the code was:-
       long[@bit_ticks][port] := (clkfreq / baudrate)
    
    which change the variables
    bit4_ticks            long      0             ' bit ticks for start bit, 1/4 of standard bit
    bit4_ticks1           long      0
    bit4_ticks2           long      0
    bit4_ticks3           long      0
    bit_ticks             long      0             ' clock ticks per bit
    bit_ticks1            long      0
    bit_ticks2            long      0
    bit_ticks3            long      0
    

    Since I am interested in changing the baud rates for ports 0 & 1, I guess I could recalculate the values of
    bit_ticks            long      0 
    bit_ticks1           long      0
    
    and
    bit4_ticks            long      0
    bit4_ticks1           long      0
    
    but am not sure if that is all that would be needed?
    It looks like that part of memory is over-written by the serial buffers anyway so I guess that wouldn't work?
  • Well it's relatively cool here in the middle of winter, 16'C at present but summers sure are hot.

    The bit ticks are used by the WAITCNT instruction to synchronize the bit timing so that for a 96MHz clock rate and 9600 baud timing the bit ticks = 10,000 for instance. So that is all that is needed really although I like to set a start bit sample time as well that is half that bit time (20,000) plus a few extra cycles to compensate for overheads.

    However it's important to realize that bitticks in the cog cannot be set directly by Spin, it can only set a hub variable and pass the pointer to those parameters during a cognew in the PAR register as @rx_head. But there is no need to stop and start the cog since the information to change the baud rate is provided in the serial data stream. If you can tell me what this command looks like I can devise a scheme to handle this in the receive cog plus give you the code for that which would probably include a modified FDS object.
    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • Thanks for that Peter, I am very interested in seeing how this is done.

    The command string is very simple just "B09600<cr>

    I was thinking about just offsetting the String by +1 and then converting the next 5 digits to decimal as the baud rate, and passing that into the code to do the change, that was when I thought it could be done in Spin of course.

    The equipment is old and will only change up to 19200 anyway, the only valid rates are 'B00300'; 'B00600'; 'B01200'; 'B02400'; 'B04800'; 'B09600'; 'B19200' and I don't think the lower 2 or 3 would ever be used.
    Also, looking at the code for "fullDuplexSerial4port" I am not sure they are supported either as they aren't mentioned in the CON section of the code, but I also don't see where the mentioned ones are used and think they are perhaps just examples.
  • Peter JakackiPeter Jakacki Posts: 6,517
    edited June 27 Vote Up0Vote Down
    I'm guessing that this string has some kind of leading delimiter such as cr/lf so that it can be detected as otherwise we only have the "B" and 5 digits plus cr to go by which is ok. We need to do this in the PASM cog to be effective which means we need to maintain a simple buffer of sorts but it would be easier if that buffer were just a single long. So I'm thinking of building a long from any "B" that is encountered and accepting only three more characters so we end up with a long that holds the 32-bit integer that corresponds to the characters "B192" or $42323932 for instance.

    However it may be simpler to accumulate all decimal digits as a binary long but any non-digit character can clear it but that character would also be latched as a "command". Therefore the B would clear the accumulator as any other character would but the B would be latched as a possible command. Then as the digits come in they are converted to binary (ch-$30) and added to the accumulator after a x10 decimal shift. When the cr is sensed it checks the "command" and if it is a B it then checks the accumulator for a valid number (and possibly a digit count) which is then used to lookup a small table of bit tick value in the PASM cog to load into bit ticks. Instantly that cog has changed its baud rate, all without any Spin overhead or stopping/starting. That sounds simple enough and it's fast and it's effective. I will look at some code shortly.

    If you have cogs to spare it is easier to assign a cog as a receive or transmit channel so these baud rates can be different.
    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • As you say, there is always a leading delimiter (trailing from the previous character really) such as <cr><lf> which is normal but a minimum is <cr> so I have just been ignoring the <lf> and treating the <cr> as the delimiter in my code. The 32 bit integer idea is where I was heading, the last 2 characters are always zeros but I was thinking they need to be converted into a number rather than left as ASCII, like you say in your second suggestion.

    My only concern in doing it all in PASM is how does the spin program know that the Baud rate has changed?
    I suppose I could still monitor these same characters in spin to determine this, they would still pass through in the serial stream in the normal way, wouldn't they? The reason this is important is that I would need to save the BAUD rate to eeprom to recall it at the next power up. Otherwise we could get the Baud rates out of sync.
    I would need to change both ports 0 & 1 at the same time as I have a COG receiving on one port and transmitting the filtered code to the other in real time (more or less), ditto for a second COG in the opposite direction, I do have a few spare cogs at the moment but suspect they will be used sooner rather then latter by some un-written routines I have planned.
    Must be getting late in Brisbane, have a good night.
  • Peter JakackiPeter Jakacki Posts: 6,517
    edited June 27 Vote Up0Vote Down
    It's only after midnight, still early :)

    The baud rate can be written to hub, perhaps even back to the bit_ticks variable. Just monitor that for a change and write to EEPROM. Since the Propeller loads 32k on boot from EEPROM mirrored to RAM you will find that the location of the hub variable in RAM is the same as it is in EEPROM, so you don't need a different location etc, just eewrlong(@myloc,myloc) or something like that and it will be automatically restored at boot.

    I'm not sure what timing issues you might have but obviously any system that changes baud rates on the fly should have some kind of delay in there, however short. This time can be used to read/write the hub although I'm not sure of the exact details that you may be aware of to make the final implementation decisions.
    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    TACHYON DEMONSTRATOR
    Brisbane, Australia
  • Tracy AllenTracy Allen Posts: 6,082
    edited June 27 Vote Up0Vote Down
    One way I've approached this is to send a special character to one of the tx ports, and use that character in the pasm code to branch to a routine that executes a patch to the parameter of interest. You would decode the change of baud rate from an rx port as you do now, in Spin, and then send the special character out the modified tx port in order to modify bit_ticksN and bit4_ticksN for whatever ports need the change.

    Here is the patch implemented on port0, the last two lines of this snippet:
    ctsi0   if_z            jmp     #transmit             'may be patched to if_z_or_c or if_z_or_nc
    
                            rdbyte  txdata,txbuff_tail_ptr '{8}
                            add     tx_tail,#1
                            cmpsub  tx_tail,txsize    wz   ' (TTA) for individually sized buffers, will zero at rollover
                            wrlong  tx_tail,tx_tail_ptr    '{8}
            if_z            mov     txbuff_tail_ptr,txbuff_ptr 'reset tail_ptr if we wrapped
            if_nz           add     txbuff_tail_ptr,#1    'otherwise add 1
    
                            jmpret  txcode,rxcode1
                            cmp     txdata,#250          wc      'this is the escape code for the watchdog
             if_nc          jmp     #Peeti                      ' command is 250,251,252,253,254,255, c set if dest < source
    
    This isolates the ascii codes from 250 to 255. The code at Peeti then applies the patch. You could use different codes for different baud rates. Those codes are not transmitted, but otherwise the port0 tx operates normally. The code at Peeti exits with a jmp #transmit. In this modified version of the 4port object, the patch was supporting a watchdog timer (Peeti is the name of my son's dog, a high strung chihuahua) via the cog counters.

  • Thank you both Peter & Tracy for some great tips. I am starting to learn a bit of Machine code this way, earlier than I had planned but that is good.
    I don't think I really appreciated just how much I still needed to learn but I am getting the idea now.
    The two different approaches to the same problem are an education in themselves.
    I am not sure I would have thought of either technique as I was thinking along the lines of restarting the 4 port COG with the new values, I now think this would probably have caused my other 2 COGs to crash since they were constantly calling the one I disabled, a whole can of worms there.
    Modifying the BAUD rates directly in the "fullDuplexSerial4port" routine seems like the way to proceed, though I will probably need more hints as I get to grips with it.
  • I have attempted both techniques today and finally decided I can just about understand what I needed to do to get Tracey's solution working.
    Sorry Peter but I just don't know enough to even attempt yours at this point.

    Below is my first poor attempt at PASM, in the form of the Peeti subroutine suggested by Tracey.
    I would need to add this routine up to 4 times, once for each channel i need to change, if i can get it working that is.
    I am trying to check the baud rates in reverse since I think the higher rates are more likely to be used and by using CMP with WC it is logical (to me) to do the higher values first and if the value is less then it falls through to the next comparison. I did toy with the idea of filtering the value of "txdata" with an "xor" filter of F8 to give a result of 0 - 7 for the baud rates but don't think this would have gained me anything much.

    I don't know how to calculate the longs for bit_ticks & bit4_ticks (shown below as {VALUEa} & {VALUEb}
    in SPIN it looks like this but can't see how I would do them in PASM, Any clues?
      long[@bit_ticks][port] := (clkfreq / baudrate)
      long[@bit4_ticks][port] := long[@bit_ticks][port] >> 2
    
    ' BAUD Rate Changes
    'if you are here the codes in the range 248 - 255 (F8- FF) were sent to the TX[port0]
    
    Peeti                                                                                   ' Set Baud rates for Serial 0 
                                            cmp     txdata,#255	        wc              ' 38400 baud IF txdata < 255 THEN C = 1
                    if_nc	                WRLONG	{VALUEa}, bit_ticks		        ' change baud rate to 38400 if C = 0
                    if_nc	                WRLONG	{VALUEb}, bit4_ticks		        ' change baud rate to 38400 if C = 0
                    if_nc	                jmp 	#transmit            
    		
                                            cmp     txdata,#254		wc	                ' 19200 baud						
    					'modified version of above code, return to #transmit                                      
    	
                                            cmp     txdata,#253		wc	                ' 9600 baud
    					'modified version of above code, return to #transmit 
    
                                            cmp     txdata,#252		wc	                ' 4800 baud
    					'modified version of above code, return to #transmit 
    
                                            cmp     txdata,#251		wc	                ' 2400 baud
    					'modified version of above code, return to #transmit 
    
                                            cmp     txdata,#250		wc	               ' 1200 baud
    					'modified version of above code, return to #transmit 
    
                                            cmp     txdata,#249		wc	               ' 600 baud
    					'modified version of above code, return to #transmit 
    
                                            cmp     txdata,#248		wc	               ' 300 baud
    					'modified version of above code, return to #transmit 
    
    
    I realize the above is probably very long winded, particularly if used 4 times but any comments about being the correct track or not with this?
    Thanks all :smile:
  • Tracy AllenTracy Allen Posts: 6,082
    edited June 28 Vote Up0Vote Down
    A couple of quick hints. Isn't pasm fun?
    Add a variable to DAT section that contains the constants that are used for patching the code.
    bit_ticks_300 long clkfreq/300
    The bit tick constants for other 7 rates that you want are easily calculated from the 300 baud constant.
    Then, (caveat emptor)
    Peeti
        sub t1, #248 .                     ' select baud rate 0 to 8
        mov txdata, bit_ticks_300    ' using txdata as temporary
        shr    txdata, t1                    ' compute ticks for desired baud rate
        mov bit_ticks1, txdata         ' changing baud on port1
        shr  txdata,#2                    ' divide by 4
        mov bit4_ticks1, txdata       ' 
        jmp #transmit   
    
    I don't think you necessarily have to write the value back to the hub in pasm, although you certainly could do so with a WRLONG. You will be decoding the new baud rate in spin, so you could update the hub version from Spin, and more importantly, the eeprom version so that it will survive a power cycle or reset.
  • Thanks for that Tracy, a bit different to mine I see :surprise: , let me see if I can follow you here.
    I have added the "bit_ticks_300" to the DAT section of "fullDuplexSerial4port.spin".

    The [ ] below gives my interpretation of the meaning of your code and some questions, like I am not sure how T1 got it's initial value?
    Peeti                                     '[Peeti here is only referring to the code for TX0 buffer, altered code will be needed for ports 1,2 &3 as needed]
        sub   t1, #248                        ' select baud rate 0 to 8 {I am guessing here that T1 somehow contains 248 at the start so it will contain 0 at the end?, does it always = 248??]
        mov  txdata, bit_ticks_300            ' using txdata as temporary [easy enough, use txdata as a temporary storage location]
        shr   txdata, t1                      ' compute ticks for desired baud rate [for #248 thus will right shift 0 bits therefore same, for #255 would this be 8 bits??]
        mov  bit_ticks1, txdata               ' changing baud on port1[confused here as I thought Peeti only operated on port 0, should that be "bit_ticks"??]
        shr   txdata,#2                       ' divide by 4 [this one calculates the bit4_ticks value from bit_ticks_300 & stores it in txdata]
        mov  bit4_ticks1, txdata              ' [now transfer txdata temp into bit4_ticks (again, this shouldn't be a 1 for Port 0 should it???)]
        jmp #transmit                         '  [return to get next TX character]
    
    You say " You will be decoding the new baud rate in spin, so you could update the hub version from Spin".
    Yes that is true, I will store the Hub version of the baud rate prior to sending the command to "Tx0" buffer from spin & also update the eeprom values from spin.

    Is my code analysis even close to the truth??
  • Tracy AllenTracy Allen Posts: 6,082
    edited June 29 Vote Up0Vote Down
    Oh, I dropped a step,
    mov t1, txdata . ' txdata contains a number from 248 to 255
    although it's more efficient written like this, (again caveat emptor)
    Peeti
        sub txdata, #248 .         ' select baud rate 0 to 8, at entry txdata contains 248 to 255, representing 300 to 38400 baud.
        mov t1, bit_ticks_300    ' t1 is scratch variable
        shr    t1, txdata            ' this divides bit_ticks_300 by appropriate power of 2, fewer bit ticks for higher baud rates.
        mov bit_ticks1, t1         '   changing baud on port1 . Peeti can change the baud rate on any port you want, or on multiple ports.
        shr  t1,#2 .                   ' divide by 4
        mov bit4_ticks1, t1       ' 
        jmp #transmit
    
    You probably don't want to change the baud rate on port 0, but it is not out of the question so long as Spin compensates too. The pasm can change the parameters for any of the ports, but only in the same cog. I'm not sure what you meant in your first post by, "separate COGs for the send and receive data paths". Your code analysis is fine except for my mistake and the bit about only being able to change port zero.

    Come to think of it, the Spin should not write anything to the hub location of the bit_ticks variables. This is because once those variables get loaded to the cog during the Start method, the contents of those locations is no longer needed in Spin, and they become repurposed as part of the data buffers. So, don't even think of putting anything there. See the note in the program in the declared DAT section, "Start of HUB overlay".

    On the other hand, Spin could update those locations in the eeprom image so that they will be loaded at startup. For that to be effective, you will have to take out the initialization of bit_ticks for the affected ports in the AddPort method. Delete the two lines from the AddPort method,
      long[@bit_ticks][port] := (clkfreq / baudrate)
      long[@bit4_ticks][port] := long[@bit_ticks][port] >> 2
    
    and instead enter your default starting baud rates in the DAT section.
    bit_ticks             long      80_000_000/9600             ' clock ticks per bit assuming clkfreq is going to be 80MHz
    bit_ticks1            long      80_000_000/9600
    bit_ticks2            long      80_000_000/9600
    bit_ticks3            long      80_000_000/9600
    
    and also for bit4_ticks. That is one way. There are other ways to do it to fill in the baud rates at Addport time.
  • OK Tracy. I was thinking I needed to add this code to each TX port 0 - 3 that I might need to change, and that it would change the rate for that port, but you seem to be suggesting that can cause problems?
    If I am understanding you correctly you intended this code to be on a fixed port (preferably one that doesn't ever have a baud rate change) but to have the code in it to change the baud rates of other specific targeted ports?
    Does that sound right??

    In my application, I use a COG to read data on Port0 & immediately send it out on Port1, but am Monitoring the bytes in some cases blocking or Adding specific bytes or strings as required. The other direction is the similar in a second COG, it reads Port1 & sends the data out on Port0 with monitoring / filtering, there is some interaction between the 2, in some cases I look for something coming in on port0, block it and set a variable to tell the other "SIDE / COG" to send back a reply. Sounds convoluted but works well and means I don't need to add any extra delays caused by buffering everything yet again.

    Due to the above I will always need both ports 0 & 1 to have the same baud rate (of course I could just change the port numbers in code if I really need to keep port 0 fixed for some reason, the other 2 serial ports will be fixed at 9600 so I could add your code to one of those.
  • Come to think of it, the Spin should not write anything to the hub location of the bit_ticks variables. This is because once those variables get loaded to the cog during the Start method, the contents of those locations is no longer needed in Spin, and they become repurposed as part of the data buffers. So, don't even think of putting anything there. See the note in the program in the declared DAT section, "Start of HUB overlay".
    I sort of knew that, but your PASM code refered to the same variable names, such as
    mov bit4_ticks1, t1
    
    so I got a bit confused.
    The former values are in Hub Ram but I guess this "bit4_ticks1" is now in COG ram with the same <local> name?
    I assume that happens because the DAT section code is copied to COG ram then executed, thus allowing you to re-use the HUB ram as buffer space, rather cleaver really.
  • Hi All.
    I now have a working Baud change routine :smile:
    I have called this version "fullDuplexSerial4Port(CB).spin" the changes to "fullDuplexSerial4Port.spin" V1.1 to allow the change Baud function.

    Full Credit to Tracy Allen for the code, all changes are marked TTA2017.
    {{  FullDuplexSerial4portPlus version 1.1(CB)
      - Tracy Allen (TTA2017) 2017_06_27 Added BAUD rate change code to TX Port0.
      One way I've approached this is to send a special character to one of the tx ports, and use that
      character in the pasm code to branch to a routine that executes a patch to the parameter of interest.
      You would decode the change of baud rate from an RX port as you do now, in Spin, and then send the
      special character out the modified TX port in order to modify bit_ticksN and bit4_ticksN for whatever
      ports need the change.
      This isolates the 8 ascii codes from 248 to 255 (F8-FF). The BaudChange code then applies the patch.
      You could use different codes for different baud rates. Those codes are not transmitted,
      but otherwise the port0 TX would operate normally.
      The code at BaudChange exits with a jmp #transmit.
    }}
    
    ' Added line to PUB Init-------------------------------------------------------------------------------------------
    PUB Init
    ''Always call init before adding ports
      Stop
      long[@bit_ticks_300] := (clkfreq / 300)               ' TTA2017 calculate value for DAT variable 
      bytefill(@startfill, 0, (@endfill-@startfill))        ' initialize head/tails,port info and hub buffer pointers
      return @rxsize                                        ' TTA returns pointer to data structure, buffer sizes.
    '--------------------------------------------------------------------------------------------
    
    '--------------------------------------------------------------------------------------------
    ' Added to the PASM routine "transmit" after "jmpret  txcode,rxcode1" (12th code line after "transmit" name)
    '--------------------------------------------------------------------------------------------
    ' TTA2017 Baud Rate Change Code
                            cmp     txdata,#248          wc     ' this is the escape code for changing the BAUD rate
            if_nc           jmp     #BaudChange    ' command is 248, 249, 250,251,252,253,254,255; c set if dest < source
    '-------------------------------------------------------------------------------------------- 
    
    '--------------------------------------------------------------------------------------------
    ' Added to the PASM routine after "Transmit3" & before the Patching constants, also specified the bit_ticks_300 constant
    '--------------------------------------------------------------------------------------------
    ' BAUD Rate Changes on Ports 1&2 controlled by Port0 Tx (TTA2017) ========================================== 
    ' if you are here the codes in the range 248 - 255 (F8- FF) were sent to the TX0 (baud Change port)
    '
    BaudChange
                            sub     txdata, #248            ' select baud rate 0 to 8, at entry txdata contains 248 to 255, representing 300 to 38400 baud
                            mov     t1, bit_ticks_300       ' t1 is scratch variable
                            shr     t1, txdata              ' this divides bit_ticks_300 by appropriate power of 2, fewer bit ticks for higher baud rates
                            mov     bit_ticks1, t1          ' changing baud on port1, routine can change the baud rate on any port you want, or on multiple ports
                            mov     bit_ticks2, t1          ' changing baud on port2
                            shr     t1,#2                   ' divide by 4
                            mov     bit4_ticks1, t1         ' changing baud on port1
                            mov     bit4_ticks2, t1         ' changing baud on port2 
                            jmp     #transmit                        
    
    'TTA2017 create an empty variables in DAT for the bit_ticks_300 constant
    bit_ticks_300           long      80_000_000/300        ' defaults to 80Mhz clock, init upgrades to actual clock, if different
    '-------------------------------------------------------------------------------------------- 
    

    My thanks too, to "Peter Jakacki" who helped get me started on this, one day I might understand enough PASM to do it your way.
  • Tracy AllenTracy Allen Posts: 6,082
    edited June 30 Vote Up0Vote Down
    Glad you got it working! Beats having to restart the ports. Now that you've dipped your toe into the pasm, feel free to jump right in!

    You've answered your own questions. When transferred to the cog, the code there refers to locations there by the same variable name they have in the hub. It only knows the hub location of that variable when that information is initialized or passed in.

    In your scenario I think it would be okay to change the baud rate on any port including the one that takes the commands. The important thing is that the baud rate change shouldn't happen in the middle of receiving or xmitting a character. The only(?) consequence of a collision would be a junk character or maybe loss of sync if the characters are sent/received in tight packets.

    Does your app use all 4 ports in each of the two cogs? Check that the sizes of the receive and transmit buffers are fixed by CONstants to what the app needs.



  • Tracy,
    My NEW Port arrangement is as follows.
    I renumbered them to use Port0 as the Baud Rate controller.

    I have lettered the COGs below just to indicate what each COG does, I don't know or care which actual COG is used for what task (yet at least).

    Quad Serial Port #
    Port 0 Fixed 9600 Baud Rx only , though this might change (Tx used to control the Baud Rates of Ports 1&2) - controlled by COG_A
    Port 1 Up-link Port - COG_B/C, see below
    Port 2 Legacy Equipment Port - COG_B/C, see below
    Port 3 Fixed 9600 Rx & Tx - COG_D

    COG_B (Rx on Port 1 & Tx on Port 2) | Most of the work is done by these 2 cogs
    COG_C (Rx on Port 2 & Tx on Port 1) |

    COG_E of course the Quad Serial Port driver itself uses one COG
    COG_F Main Program startup also uses one but I may stop this after startup but is left looping for debugging at the moment
    COG_G I2C driver
    Does your app use all 4 ports in each of the two cogs?
    I have detailed my usage above for you, but no, I only Transmit & Receive in the same COG, not necessarily to the same port though, as explained above.
    I have structured my code so that all TX to a specific Port is from a specific COG for example.
    I wasn't sure it was wise to try transmitting (or receiving) from different COGs, looked too complicated.

    Having said that I am not sure how much buffer space I will need in any of these, the defaults seem to work fine, so far at least.


  • I would like to ask a question about something I added the code below, to Init in my code above:-
    long[@bit_ticks_300] := (clkfreq / 300)               ' TTA2017 calculate value for DAT variable
    
    as I couldn't think of another way to make sure the variable would be correct regardless of the clock speed as you don't seem to be able to do calculations with variables in the DAT section.
    It seems to work OK but would there have been a better way of doing this? It seems like I am doing the same thing twice.
    In my Case the the 80Mhz/300 is fine but if I change the crystal to 6Mhz I would want the same code to work there as well without having to change the driver code for all permutations.
    'TTA2017 create an empty variables in DAT for the bit_ticks_300 constant
    bit_ticks_300           long      80_000_000/300        ' defaults to 80Mhz clock, init upgrades to actual clock, if different
    
    Any hints of doing this in a better way?
  • That is a good way to do it, in the Init method. Whatever you put there will override the default value, 80_000_000/300. The default value might as well be zero unless you just leave the calculation there as a reminder.

    When the Prop reset, will it need to maintain the current baud rate, that might have been changed during operation? The current baud rate values have to be stored somewhere in the eeprom.

    I'm still mixed up, not understanding the mix of cogs and ports, or I'm wondering if it is your misunderstanding.
    COG_E of course the Quad Serial Port driver itself uses one COG
    COG_F Main Program startup also uses one but I may stop this after startup but is left looping for debugging at the moment
    COG_G I2C driver
    The Spin code for the 4-port object would normally be running in what you call COG_F, and its PASM component to service 4 ports would be in an auxiliary cog launched by the Start method.

    Unless there is some speed bottleneck, it looks like all of the serial ports 0 to 3 could fit into 1 pasm cog. I don't understand why you mention using 5 cogs in connection with the serial port driver, A, B, C, D and E. How so?


  • Hi Tracy, You could be correct, perhaps I am doing this all wrong, this is my first attempt at using the Propeller Chip and I am still very much a learner. 3 months ago I had never programmed one so my understanding could be at fault here.
    Broadly I am trying to upgrade some old equipment to add functions but leaving existing functions intact (for the most part). To do this I need a lot of serial ports as will as I2C for the Real time clock & IMU units.
    I then "Peek" at the main data stream (in both directions) & depending on what I see can block the data or "Poke" some extra strings into the data stream.
    At startup the code is loaded then runs MAIN.
    MAIN just populates some defined VARs then does the initialization & loads my default drivers [i2c, UARTs (your "4 serial ports 0 to 3 could fit into 1 pasm cog") & DEBUG - all in separate COGs] then runs my SPIN code to deal with the comm ports, in separate COGs (these deal with the data streams & communicate with the driver).

    Serial Ports 1&2 are where most things happen & I treat these as 2 separate paths (Rx on Port 1 & Tx on Port 2) in one COG & (Rx on Port 2 & Tx on Port 1) in another COG. I have about 250 lines of Spin code running in each of these COGs.
    It is possible I might eventually move the other 2 serial ports back into these 2 cogs as well as they are very simple but at the moment they are a COG each as well. This is all a steep learning curve for me and perhaps I will discover I am doing it wrong but it seems to be working well to this point.
Sign In or Register to comment.