CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Redirect STD IO to external fifo UART - Streams - How ?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

Redirect STD IO to external fifo UART - Streams - How ?
PostPosted: Tue Nov 20, 2007 8:24 pm     Reply with quote

My problem is with understanding how to implement a user defined Stream that intercepts stdin and stdout
calls , such that the whole family of std i/o serial related functions ( putc, getc, printf, kbhit etc ) are directed to MY routines for use with an external polled 16550 family UART -

i have plenty of experience with hardware coding for the 16c550 - thru the 16c1054 (my current favorite).
This is for an application using the ADS-8371 750KS 16 bit A/D - w parallel alternating byte access - 16f887 control on the E port - Data reception on the D port and D port shared with a LOT of 74HC574 aux expansion latches- and other stuff , and ideally real soon - the 16c1054 too. The UART has its own clock source.

the A port has address select lines for the 82c54, ADS8371 and 16c1054 ( think of it as a 16550 FIFO UART on steroids )
Even running at the full 20 mhz, the timing overhead of the internal rs232 UART in the 887 is a huge time sucker compared to how fast samples are available from the A/D - (i've been using 57.6kbaud after some jerking around - but thats another story) My zippy a/d is just grossly wasted as the characters dribble out by comparison-

the answer for me is an EXTERNAL hi performance UART with nice deep fifos and parallel transfer into it - with no wait states - and a simple check if new data can be dumped into the internal circular transmit fifo
( all the data volume is on the sending side w 4 hex chars per sample )
using the EXTERNAL UART at a steady 115K or 230Kbaud output - which is received and converted using a DIGI Edgport serial to USB adapter and then transferred to the PC host as a USB stream - via the windows com device API - stunningly fast ( parallel access to dump that data HAS to beat the pants off ANY baud rate on the internal UART)

I want to be sampling data instead of waiting of the on board UART
pinch out the bits.

Because the D port parallel bus is shared in common with latches,the A/D and an 82c54 ( as well as soon - the 16cxxxx uart) -AND other devices - that all have multiple byte access states possible, interrupts are totally not feasible. a deep fifo external UART that is polled - solves that nicely IF if can figure out how to cleanly make MY handlers for it - connect to std io functions
is there any guidance i can read on that ?

i looked at examples like modbus ( using the intrernal RS232 ) and the rs483 422 examples - but again - its the internal #use RS232 statement directed to an alternate stream modifier but mapped to the internal UART. I'm sorry to admit it - but those examples are so clouded by macro pre processor statements ( and UN commented in line with the code) that it is all as clear as mud to me.

if anyone can point me in the general direction that would let me get a grasp of how to redirect those STDIO streams - and the internal mechanisms for "#USE " of my virtual polled serial device for STD io -
// i would be forever ( or at least for
delay_ms(100000000) );
// grateful

IF this has been answered well before- please excuse my ignorance for not digging deep enough to find it.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 20, 2007 11:50 pm     Reply with quote

The CCS printf() function has a feature that allows re-directing the
output to another function. The printf output is sent to the specified
function, one character at a time. For putc(), getc(), etc., you'll have
to write your own functions.

See the sample code in the link below. It shows how to write your own
serial i/o functions for a PIC and a version of the compiler in which the
built-in functions don't work. You'll have to do something similar to this,
except make it work with your external UART.
http://www.ccsinfo.com/forum/viewtopic.php?t=26631&start=7
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

much clearer now
PostPosted: Wed Nov 21, 2007 4:54 pm     Reply with quote

so if i am getting this right - the 'stream' is basically a reference to my replacement function for the actual I/O operation.
very helpful to get that concept from you T H A N K S.

of course the method described has a remaining, glaring performance weakness for REALLY hi thru put I/O in that it is character based.

You see - there is some small overhead in using the external UART in that
(without dedicating precious PIC pins to a HARDWARE FIFO status poll on the UART chip ) some register setup is still required to know if more characters can FIT before the transfer begins to the UART FIFO .

it adds up to about 30 instructs - just getting ready

but once done - transfers across the D bus of MULTIPLE chars can go VERY fast =- as in with fast IO it is 7 PIC instructs per byte moved to the UART
( mov data to D port - toggle Not_WRT on UART basically )

- by only getting single chars at a time from the print formatter - while it should still be be MUCH better than the using the internal UART rates -there are many more kind-of wasted cycles associated with the formatting beforehand - as each character still carries my handler overhead but only getting ONE byte moved at a time for the setup .
--------------------------------
the IDEAL formatter would pass a PTR to a string already done and ready to transmit - that would be an awesome solution - but is not in the cards right ? after scouring the V4 ref manual no printf variant that does anything caught my attention. ( BTW: i would pay EXTRA $$ for a well doen INDEX to that manual )

i have no problem sharing the finished code once i'm certain to have wrung out all the waste i can - so any ideas that would break thru that last item would be great to incorporate

do you think the port choices i have made are generically useful to others ?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Nov 21, 2007 7:52 pm     Reply with quote

Just wondering...
If you want to transmit the data over USB, why use the serial UART as an intermediate? Directly sending the data to a parallel USB tranceiver like the FTDI FT245BL will reduce component count and increase throughput by at least a factor 6 (230kbit serial v.s. 1.5Mbit for slow USB 1.0 device).

In the PIC18 series there are processors with an inbuilt USB tranceiver reducing component count even more. Additional advantages of the PIC18 over the PIC16 are a more efficient instruction set, higher clock frequency (48MHz vs. 20MHz) and larger memory. The 16c1054 has a FIFO of 256 bytes, the PIC chips have 1k (configurable for Tx and Rx)...
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

why serial service at all? customer $$ call the shots -
PostPosted: Wed Nov 21, 2007 9:22 pm     Reply with quote

if only it was so simple as me saying - we will use this interface and do it like so . but there are
serveral reasons for staying serial -
the gizmo in question is a very specialized data acq head end
product used in Bio /drug research and it comes
with a big legacy ball and chain - and mostly, computer non-savy user base to match

1- one legacy aspect is keeping compatibility with an older - slower sampling version of roughly the same product -- which has according to MY customer - always been well handled by serial services and an existing user base, some of whom still use old WinDoze versions of the application.

2 - i'm using both channels of a MAX 223 for TWO serial ports - ONE is a local monitor where the received data lines from RS-232 come out of the MAX 222 and are ANDED together for a data tap - monitor - before connecting to the UART RECV pins - and UART Transmit drive is paralleled to BOTH send sides of the 222.
this feature is easy to maintain with the Edgeport for Newer PCs with ONLY USB on board. The second serial port is a free standing data recorder that can grab and store the specific serial data format the gizmo makes

3- i'm not in control of the PC apps that this works with and the spec i am meeting is driven by the porting of my customer's $$$ to my bank account.
All this is more or less spec'd by a chief scientist who is (a) a Nobel prize winner in the field (b) 71 years old - still with the company and cranky as a bat at noon hour.


in the world of commerce - the one who writes the checks gets to tell the
one who bangs the bits how they want them served.

Rolling Eyes
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

about the SPAM line above NOT MY TYPING!!
PostPosted: Wed Nov 21, 2007 9:24 pm     Reply with quote

the cool BBS system translated the word i typed B-I-O / D-R-U-G into the word S-P-A-M
above - never saw anything so bizarre before on a board ???????????????
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Nov 22, 2007 8:46 am     Reply with quote

Backwards compatibility says it all...

Be careful though, high speed RS232 can cause lots of problems especially with longer or bad quality cables. Not to mention the difficult timing problems we had using external RS232 to USB converters.

I'm sure you can make it work but the architecture you describe sounds sub-optimal. You are using one of the smaller PIC processors to which you have added an external timer module, port extenders and now an external UART. Isn't it possible to use a more advanced (PIC) processor with more timers, enhanced UART higher clock frequency and higher pin count so you could get rid of all those external components? It would simplify your design a lot and removes interfacing overhead.

For example the PIC18 has two hardware interrupt levels so you can separate the timing critical data acquisition from the rs232 transmission.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

what can be done ?
PostPosted: Thu Nov 22, 2007 9:25 am     Reply with quote

all clear and understood - but the external latches and timer are essential to a safety aspect of the system that has been carefully evaluated and approved by the customer - and i have the long standing rule of not breaking what is already working pretty well. and i only get paid ONCE for the project so digging up the foundation is not in the budget.
SET



Joined: 15 Nov 2005
Posts: 161
Location: Glasgow, UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Nov 22, 2007 9:30 am     Reply with quote

Quote:
all clear and understood - but the external latches and timer are essential to a safety aspect of the system that has been carefully evaluated and approved by the customer - and i have the long standing rule of not breaking what is already working pretty well. and i only get paid ONCE for the project so digging up the foundation is not in the budget.


Totally sympathise with your dilemma Smile . We often get involved in projects, that all things being equal, could be done bettter if redesign was an option. Especially applies to medical, once a design is done it's very hard to move it by much.
SET



Joined: 15 Nov 2005
Posts: 161
Location: Glasgow, UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Nov 22, 2007 9:38 am     Reply with quote

Quote:
You see - there is some small overhead in using the external UART in that
(without dedicating precious PIC pins to a HARDWARE FIFO status poll on the UART chip ) some register setup is still required to know if more characters can FIT before the transfer begins to the UART FIFO .

it adds up to about 30 instructs - just getting ready

but once done - transfers across the D bus of MULTIPLE chars can go VERY fast =- as in with fast IO it is 7 PIC instructs per byte moved to the UART
( mov data to D port - toggle Not_WRT on UART basically )

- by only getting single chars at a time from the print formatter - while it should still be be MUCH better than the using the internal UART rates -there are many more kind-of wasted cycles associated with the formatting beforehand - as each character still carries my handler overhead but only getting ONE byte moved at a time for the setup .


Just thinking aloud here - the user routine passed to 'printf' could maintain an internal state, and buffer chars too (static variables), so could perhaps give you the best of both worlds? ('transparent' usage of printf, and the external UART performance)
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Nov 22, 2007 10:43 am     Reply with quote

SET wrote:
Just thinking aloud here - the user routine passed to 'printf' could maintain an internal state, and buffer chars too (static variables), so could perhaps give you the best of both worlds? ('transparent' usage of printf, and the external UART performance)
Continuing to think in the same line:
Maybe it is possible to add a special terminating character to the strings? The customized putc() function buffers all data until it detects the 'flush' character.

An alternative approach is to have the customized putc() function buffer the data until either one of the following occurs:
1) a defined number of characters is in the temporary buffer, let's say 10 characters.
or
2) a time out has passed since the last character was added to the internal temporary buffer, let's say 100ms. (requires a low priority interrupt).
This same algorithm is being used in several TCP/IP stacks but I can't remember the name for it.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

excellent suggestion
PostPosted: Thu Nov 22, 2007 11:05 am     Reply with quote

i think that using a reserved character is a superb suggestion and very do-able in my case. and of course there is a natural free one here too.
i feel so d-u-m for not thinking of it myself.

all i really have to do then is format the string handed to printf with a \r and wait for the carriage return to be handed to my_putc() in the stream before moving the whole thing to the fifo. not as perfect has having a printf that shares a buffer - or hands a ptr to the finished string - but as close as we are gonna come i think. excellent suggestion.

it is really humbling to find so many sharp people here. i spend too many frustrating ( but paid ) hours with my customer's two alleged V.B. programmers, who i personally wouldn't trust to code Hello World for me.

i admit i had some grave doubts after reading topics like "how do i declare a global variable" and so on - but the moderator and folks who have replied are terrificly clever and generous with smart suggestions. I am indebted to you all. and THANKS to all too.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group