Searching \ for '[SX]: Dual UART & IIC multimaster virtualperiphera' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page:
Search entire site for: 'Dual UART & IIC multimaster virtualperiphera'.

Exact match. Not showing close matches.
PICList Thread
'[SX]: Dual UART & IIC multimaster virtualperiphera'
2001\09\14@034211 by Russell McMahon

picon face
Has anyone successfully used the Ubicom sample dual UART & IIC multimaster
virtual peripheral ?

I've just returned to a project where I'm intending to use this code.
The dual UART had a fatal flaw which I have fixed. This probably came from
someone having duplicated code for a single UART but missing a common flag
fatally shared between the two routines - possibly OK if only one was active
at once and you changed serial connections over to test each in turn. I've
added a 3rd UART to this and they all work OK.

I've just started on the IIC (where I only need a single master) and at
first try it appeared "dead in the water".
I added a debugging call to a print routine part way through the code. This
needed a bank switch and I then restored the bank to where it "should" have
been after the serial call, and lo & behold, it burst into somethinfg like
life. Removing the serial call but keeping the subsequent bank call (which
should now be redundant) and it still works partially. This suggests the
basic code is flawed. If anyone else has used this with success I'd love to
hear from them. I'll no doubt get it going but short circuiting having to
fix something which isn't meant to be broken would be nice.

I'd like to think that it was just something I was doing wrong but the fact
that the UART was definitely broken suggests the other problem also may be


               Russell McMahon

-- hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads

2001\09\14@080526 by Mr MCU

As a matter of course, I never use any supplied code without going through it
first and debugging it.  I look at them as SAMPLES!  I always make changes ...

- Mike

-- hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads

2001\09\17@073210 by Russell McMahon

picon face
> I have also been looking at the multiple UART code supplied by Ubicom
> and found that the 8 UART code was also fatally flawed. The problem
> that I found was that at maximum baud rates, the code degenerated
> into doing only 1x oversampling of the input, which obviously would
> never work reliably, if at all. I wrote Ubicom about this and they
> indicated that they were aware that some of their samples were very
> buggy and were dropping them from their web site as a result.
> My need is to run 5 UARTs at 19200 or 38400 baud full-duplex, and I
> am just beginning to develop code for this.  I ran the calculations
> and it looks like it can be done at 50 MHz, but just barely. If you
> can provide any working samples that would be helpful, it would be
> most appreciated. I will be doing some IIC later, but haven't looked
> into that yet.

Nothwithstanding the "sample" state of the code I was surprised to find that
it was fatally imperfect - certainly so in the case of the UARTS and
apparently so (so far) i the case of the I2C.

The 2 UART code from the "I2C plus dual UART" should be extendable to 8
UARTS although you may have to look carefully at RAM usage..
I have extended it to 3 for my purposes and they seem to work OK.

Ubicom give the worst case send and receive time for 1 UART as 36 cycles
At 50 MHz and 50% utilisation and 38,400 baud you have about
50,000,000 / 38400 /2 /36 = 18 worst case UART send / receive calls.
This is indeed a "little tight" as it gives 18/8 = 2.25 UART calls per bit.
However this is worst case wiRX & TX in worst case mode every call whereas
most of the time they will not be.
Typical is probably 30 to 32 cycles - still tight but rememebr - this is at
50% cpu utilisation so there's a bit of slcak there.
Quite possibly you could "cheat" and gang all transmitters in lock step so
you start all active tx bytes at once and have an 8 bit parallel UART
routine. This should be able to be made much more cycle efficient. A new
character on a previously idle channel waits until the end of the current
cyel time and doesn't start asynchronously as it does now. The receivers do
not "know" about this synchronism. This "trick" cannot of course be applied
to the receivers  as they are from independent sources.

Re my change for RX - simple but necessary -
1.    Flaw in code is that the receive data ready bit is in a register in
the common RAM.
All UARTS set and clear the same bit so simultaneously arriving characters
will interfere with each other via this ready bit.

The simple fix is to use a bit in the RAM associated with each UART.
See "code" at end.

Whe the RAM is paged to the bank that belongs to that UART the proper bit is
An alternative would be for each UART to have its own but in common RAM.

2.    The original dual UARTS were  in series within the same interupt tick.
Every N ticks the UART code was run BUT only one or other of the UARTs code
was run in that tick - they use a 0/1 bit to pass control to successive

I am only running at 4800 bps (set by existing equipment) which makes the
requirement less demanding
I slowed the interupt rate and adjusted the ticks per uaRT call
I then followed one UART with code for another to be run subsequently.
ie every N IRQs run a or b UART code
a = UART 1
b = UART 2 & then 3

UART 3 is now somewhat non-isochronous (ie its calling times "jitter" ) due
to the variable time taken by the preseding routine but this is acceptable.
Delays could be added if desired to UART 2 to make the code isochronous
(constant time to run under all situations).

Extra UARTS could also be added by adding extra parallel threads.
ie while each UART runs every N irqs they are staggered as to starting pont.
This is a standard method and necessary to get full processor utilisation.

More anon

       Russell McMahon



; **** This is where the receive status flag is defined
;        The simple but important change markeD ==> below
;         allows both UART receivers
;         to work indepently, as they are intended to.

; Global Register definitions
; NOTE: Global data memory starts at $0A on SX48/52 and $08 on SX18/20/28.
 org     global_org

main_temp equ global_org+1
isr_temp equ global_org+2  ; Temporary variable used by the ISR.
flags  equ global_org+3

; Replaced by bit in rx bank "rxflag"

; **** This bit is common to ALL UARTS (fatal)
uart_rx_flag  equ flags.0  ; flag set when data received by UART

active_uart_isr_flag  equ flags.1  ; uart flag used in ISR to switch between

; =====================================================


; Bank 2 - Serial bank


; ******** Standard assigns for serial receive.
 org     bank2_org
BANK2  = $
SERIAL1  =       $ ;UART bank 1
tx_high  ds      1 ;hi byte to transmit
tx_low  ds      1 ;low byte to transmit
tx_count ds      1 ;number of bits sent
tx_divide ds      1 ;xmit timing (/16) counter
rx_count ds      1 ;number of bits received
rx_divide ds      1 ;receive timing counter
rx_byte  ds      1 ;buffer for incoming byte
string  ds 1 ;used by send_string to store the address in memory
byte  ds 1 ;used by serial routines
hex  ds 1

; ==> ****** Here is the extra assignment needed for the local receive flag.

ruslrx  ds 1 ; rusl ..debug rx receive data bit
rxflag  equ ruslrx.0
ruslin  ds 1

-- Going offline? Don't AutoReply us!
email with SET PICList DIGEST in the body

2001\09\17@095102 by Bob Ammerman

picon face
See my code at PICLIST.COM,, that
implements 8 receive UART receive channels by performing all the operations
in parallel (using 'vertical math'). This code will handle up to 8 channels
at 9600 baud on a 16F84 at 20Mhz. You can save a little time by pulling out
a few instructions in the interrupt handler since you only want 5 input

The transmit side can  be implemented using similar vertical math
techniques, and should require less code per interrupt. Alternatively, since
the timer interrupt is 3x the bit rate, you could use more conventional
techniques and handle two outgoing channels on one interrupt, 2 on the next
and the remaining 1 on the third in each group of 3 interrupts.

With these techniques you should be able to handle 5 full duplex 19,200
channels at 50 Mhz CPU rate.

Bob Ammerman
RAm Systems
(contract development of high performance, high function, low-level

{Original Message removed}

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