Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Help. Trying to decide on tools and approaches.

0 views
Skip to first unread message

ScottM

unread,
Mar 18, 2006, 9:51:04 AM3/18/06
to
I'm newish to embedded work, and my last embedded project involved
Javelin process and Java, which is a tame introduction. Now I need to
move up to something faster and more flexible, but I've having as heck
of a time getting information from vendors, who can smell a hobbyist,
and have better things to do than answer their emails. I'm hoping
someone here will be more tolerant of a newbie. I need advice; if I'm
going to spend money, I have to get a successful result. I have a lot
of questions.

I want to use PC104, because I'm trying to minimize the component count
and hookup labor, and I need ethernet and 4 serial ports, with the
possibility of someday adding more serial ports or USB. I also need at
least 16 I/O pins: 4 of them analog out at 0-10v (to talk to a
commercial dimmer), 2 of them analog at 0-~20v but accuracy is not a
concern, the rest can be digital at TTL levels. I can always use more
TTL I/O.

I priced PC104 periphials boards with DACs, and started seeing $200 and
up. Since the analog outputs drive dimmers, I don't need very high
accuracy, so I hit on the idea of using a fast interrupt rate and doing
1 bit PWM in software. I think I can go as low as 4k/sec with 8 bit
overflow counters and still get a useful output for a dimmer.

But then I was told that taking 4k interrupts/sec on a PC104 running at
133Mhz (AMD elan processor), AND trying to do ethernet connectivity and
serial work, might be pushing it. And 4k/sec is about the slowest I can
go if I want to avoid visible flicker from the dimmers at the dimmest
rates. So now I'm worried about this approach. So my first question is
whether I need to splash out on a DAC board and how that can be done
cheaply. Cheap is the watchword for this project

The next is about the OS and toolchain. After pricing a few options and
coming away in shock at what people charge for development
environments, I'm leaning towards DOS and the free Digital Mars C++
compiler. I figure DOS on a PC104 has to be about as tried and true as
it gets. Unfortunately, my first day out the the Digital Mars compiler,
I hit a compiler bug, and I'm wondering if I should use something else.
Open Watcom proved to be pretty unstable (the tools kept hanging, and I
wasn't completely happy with the code generation - it was using obscene
and unwarranted amounts of stack space.) Am I better off with something
other than DOS? I priced some commercial products and they are out of
the question. I looked at linux, but I'd have to write device drivers
to get to the I/O ports and interrupts, and I'd rather not.

I need a simple audio output, and I would have liked it to be
polyphonic, so I was considering doing more PWM during my 4k
interrupts. (The tones I want to play can all be between 220Hz and
880Hz and I can pick them as I please). But if 4k/sec is unreasonable,
I'm willing to settle (unhappily) with monophonic tones and
reprogramming timer 2 (the PC104 has an output pin tied to timer 2, so
it has the advantage of being simple.)

That leads to the question about timer 0. I remember from my DOS days
that reprogramming timer 0 is everyone's favorite trick, except it can
mess up the floppy drive, which uses the 55ms ticks to time things. The
PC104 I'm looking at reads a flash card, not a floppy, so I assume I
can take over int08 and lose nothing but DOS's daytime clock (which I
don't need). Is this safe? Most of the interrupts will just do a few
instructions of calculations for the PWM, but every 64th would branch
off into a few hundred instructions. I don't really worry about how
slowly my main loop runs - even if the processer was 75% dedicated to
the interrupt code, that's enough, but I worry alot about delaying
other interrupts and missing ethernet traffic. Is that a concern?

DOS doesn't come with a TCP stack, and I need both TCP and UDP,
nonblocking. What's good? I'm willing to spend some money on a small,
stable stack, because I remember from decades ago what unstable stacks
were like.

Finally - memory. My app is mostly written, and it looks like it's
about 330k or so. But it will grow over time. I need 32 bit integers. I
assume I want DOS32 and extenders for this because the code could grow;
but I've never mixed interrupts and extenders before. Are there any
special caveats?

I apologise for the ignorance. My strength is in coding, and I can
write very tight, fast C++ and assembler code, but I'm used to
professional tool chains and detailed documentation, and this is a
project that has neither. Plus I can't afford to buy hardware and then
find out my approach is simply not going to work. I'm looking for
simple, tried and true. My preference is always for doing things in
software - I have high levels of confidence in my software ability, but
low levels when it comes to hardware.

If someone has been down this path, I would deeply appreciate guidance.
Thanks.

Mike Anton

unread,
Mar 18, 2006, 4:24:16 PM3/18/06
to

"ScottM" <sc...@mayo.name> wrote in message
news:1142693464.3...@z34g2000cwc.googlegroups.com...
<snip>

> But then I was told that taking 4k interrupts/sec on a PC104 running at
> 133Mhz (AMD elan processor), AND trying to do ethernet connectivity and
> serial work, might be pushing it. And 4k/sec is about the slowest I can
> go if I want to avoid visible flicker from the dimmers at the dimmest
> rates. So now I'm worried about this approach. So my first question is
> whether I need to splash out on a DAC board and how that can be done
> cheaply. Cheap is the watchword for this project

Well I've done at least 20K interrupts a second on an old 20MHz 286, so
4K should be a no brainer. Alas, I don't know how much CPU time was
used to service the interrupt.
>
<snip>

> That leads to the question about timer 0. I remember from my DOS days
> that reprogramming timer 0 is everyone's favorite trick, except it can
> mess up the floppy drive, which uses the 55ms ticks to time things. The
> PC104 I'm looking at reads a flash card, not a floppy, so I assume I
> can take over int08 and lose nothing but DOS's daytime clock (which I
> don't need). Is this safe? Most of the interrupts will just do a few
> instructions of calculations for the PWM, but every 64th would branch
> off into a few hundred instructions. I don't really worry about how
> slowly my main loop runs - even if the processer was 75% dedicated to
> the interrupt code, that's enough, but I worry alot about delaying
> other interrupts and missing ethernet traffic. Is that a concern?

The standard way of handling the timer 0 interrupt, is to speed it up to
whatever
you want, and then figure out when the timer would have overflowed, and then
call the old interrupt handler. This way, anything the BIOS uses the
interrupt
for is still handled, and DOS time still runs at the correct rate.

<snip>

I hope this is helpful,

Mike Anton


Steve Calfee

unread,
Mar 18, 2006, 8:33:32 PM3/18/06
to
On 18 Mar 2006 06:51:04 -0800, "ScottM" <sc...@mayo.name> wrote:

>I priced PC104 periphials boards with DACs, and started seeing $200 and
>up. Since the analog outputs drive dimmers, I don't need very high
>accuracy, so I hit on the idea of using a fast interrupt rate and doing
>1 bit PWM in software. I think I can go as low as 4k/sec with 8 bit
>overflow counters and still get a useful output for a dimmer.
>
>But then I was told that taking 4k interrupts/sec on a PC104 running at
>133Mhz (AMD elan processor), AND trying to do ethernet connectivity and
>serial work, might be pushing it. And 4k/sec is about the slowest I can
>go if I want to avoid visible flicker from the dimmers at the dimmest
>rates. So now I'm worried about this approach. So my first question is
>whether I need to splash out on a DAC board and how that can be done
>cheaply. Cheap is the watchword for this project
>

Where do you plan to get the tcp/ip stack? That may be the most
difficult issue.

>The next is about the OS and toolchain. After pricing a few options and
>coming away in shock at what people charge for development
>environments, I'm leaning towards DOS and the free Digital Mars C++
>compiler. I figure DOS on a PC104 has to be about as tried and true as
>it gets. Unfortunately, my first day out the the Digital Mars compiler,
>I hit a compiler bug, and I'm wondering if I should use something else.
>Open Watcom proved to be pretty unstable (the tools kept hanging, and I
>wasn't completely happy with the code generation - it was using obscene
>and unwarranted amounts of stack space.) Am I better off with something
>other than DOS? I priced some commercial products and they are out of
>the question. I looked at linux, but I'd have to write device drivers
>to get to the I/O ports and interrupts, and I'd rather not.
>

I just finished a product with a pc100 and freedos. I used openwatcom.
It has an extender to do 32 bit mode. I had a problem with the latest
freedos version trying to boot from compact flash, but one revision
older worked fine. For some reason the latest would not read
config.sys from flash.

I thought the openwatcom was a pretty good package. I could not figure
out how to mix C and C++ (some of the inherited code used c++), so I
just used the C++ but limited myself to what I know, C.

It was like a trip down memory lane using dos calls I had not dealt
with since 1988. However, my simple app worked fine.

>
>DOS doesn't come with a TCP stack, and I need both TCP and UDP,
>nonblocking. What's good? I'm willing to spend some money on a small,
>stable stack, because I remember from decades ago what unstable stacks
>were like.
>

See above, unless you are pretty experienced with ethernet it may be
difficult. I have not used it but uip looks very interesting. Also,
depending on what you are doing there are serial to ethernet boards
that will simplify your problem, but maybe add to your costs some. Are
you sure you found a pc100 card with ethernet?

>Finally - memory. My app is mostly written, and it looks like it's
>about 330k or so. But it will grow over time. I need 32 bit integers. I
>assume I want DOS32 and extenders for this because the code could grow;
>but I've never mixed interrupts and extenders before. Are there any
>special caveats?
>

Yes, but the openwatcom stuff worked fine with interrupts. You cannot
even buy small dram so you will probably get 32Mbytes on your PC104,
plenty of room to grow.

>I apologise for the ignorance. My strength is in coding, and I can
>write very tight, fast C++ and assembler code, but I'm used to
>professional tool chains and detailed documentation, and this is a
>project that has neither. Plus I can't afford to buy hardware and then
>find out my approach is simply not going to work. I'm looking for
>simple, tried and true. My preference is always for doing things in
>software - I have high levels of confidence in my software ability, but
>low levels when it comes to hardware.
>
>If someone has been down this path, I would deeply appreciate guidance.
>Thanks.

Been there, done that, suffered some.

Regards, Steve
There is no "x" in my email address.

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----

Roman

unread,
Mar 18, 2006, 8:54:58 PM3/18/06
to

<snip>

> I priced PC104 periphials boards with DACs, and started seeing $200 and
> up. Since the analog outputs drive dimmers, I don't need very high
> accuracy, so I hit on the idea of using a fast interrupt rate and doing
> 1 bit PWM in software. I think I can go as low as 4k/sec with 8 bit
> overflow counters and still get a useful output for a dimmer.
>
> But then I was told that taking 4k interrupts/sec on a PC104 running at
> 133Mhz (AMD elan processor), AND trying to do ethernet connectivity and

I am no an expert on PC104, but in my opinion 4k/s interrupts written in
tight assembler should be very little load on your CPU. All the other
hardware (ethernet, serial) is usually using buffers and DMA and should
require little CPU attention.

> The next is about the OS and toolchain. After pricing a few options and
> coming away in shock at what people charge for development
> environments, I'm leaning towards DOS and the free Digital Mars C++
> compiler. I figure DOS on a PC104 has to be about as tried and true as
> it gets. Unfortunately, my first day out the the Digital Mars compiler,
> I hit a compiler bug, and I'm wondering if I should use something else.

Email Walter (author and maintainer) with bug description, he seems to
be quite actively supporting the compiler.

> Open Watcom proved to be pretty unstable (the tools kept hanging, and I
> wasn't completely happy with the code generation - it was using obscene
> and unwarranted amounts of stack space.) Am I better off with something

This was my selected tool for DOS work, did not look at stack spaces
though :)


Good luck
Roman

Peter Wallace

unread,
Mar 18, 2006, 10:42:08 PM3/18/06
to

Other than interrupt latency problems from bad BIOS or Ethernet driver
code, 4KHz should be no problem.

One thing you might consider is to use interleaved PWM instead of
straight PWM, This will increase your ripple frequency so that your PWM
filters are less of a compromise between response time and output ripple.

Interleaved PWM can be generated easily by bit reversing the reference
count of the PWM generator before comparing it with the PWM value.

For example with your 8 bit at 4KHz, normal 50 % PWM would be 128 counts
high and 128 counts low = a ~16 Hz square wave. With interleaved PWM, 50 %
PWM would be 1 count high and 1 count low = a 2KHz square wave = much
easier to filter...

Peter Wallace

ScottM

unread,
Mar 19, 2006, 9:43:58 AM3/19/06
to
>For example with your 8 bit at 4KHz, normal 50 % PWM would be 128 counts
high and 128 counts low = a ~16 Hz square wave. With interleaved PWM,
50 %
PWM would be 1 count high and 1 count low = a 2KHz square wave = much
easier to filter...

;;dimmer and dimmer rate are 8 bit unsigned char arrays; this handles
channel 1 of 0-7
;;channels
mov AH, dimmerrate+1 ;;0 off, 255 full on
add dimmer+1, AH ;;running sum
setc AL ;;on if overflowed, else off
AL's low bit is what the required pin gets set to, every time through.
It does mean an out instruction on every interrupt, but I think this
works and I don't know of a faster way to get easily filtered and
quickly computed PWM output for dimmers. If someone does, let me know.
(In practice, I do this for each channel, gathering the carry bits into
a single byte, and do the out once, for all channels). Note it doesn't
ever hit 100%, but seeing as the dimmers and light bulbs aren't the
last word in precise accuracy, I expect 99+% is fine.

I'm not so worried about the dimmer computation. But every 64th
interrupt I do have a few hundred other instructions to run through,
and I just have no idea if that's going to be enough to affect serial
or ethernet handling. "Try it and see" is just what I'm trying to avoid
- it's the kind of bug that will fail only once every blue moon, which
is when my customers tend to show up. :-/.

I expect I need to do a lot of research on ethernet packet drivers and
timing requirements. I think I'm hoping someone will tell me they
calculated pi to a thousand decimal places during timer ticks, and it
never affected anything. :-)

I've gotten in contact with Walter @ digital Mars, and he's looking at
the compiler bug.

Thanks.

Peter Wallace

unread,
Mar 19, 2006, 10:22:21 AM3/19/06
to
On Sun, 19 Mar 2006 06:43:58 -0800, ScottM wrote:

>>For example with your 8 bit at 4KHz, normal 50 % PWM would be 128 counts
> high and 128 counts low = a ~16 Hz square wave. With interleaved PWM, 50
> %
> PWM would be 1 count high and 1 count low = a 2KHz square wave = much
> easier to filter...
>
> ;;dimmer and dimmer rate are 8 bit unsigned char arrays; this handles
> channel 1 of 0-7
> ;;channels
> mov AH, dimmerrate+1 ;;0 off, 255 full on add dimmer+1, AH
> ;;running sum
> setc AL ;;on if overflowed, else off
>

I think you missed my point about interleaving the PWM, With your current
system (straight 8 bit PWM) you end up with a 16 Hz PWM (4Khz/256) - 16 Hz ripple
frequency. Which means you will need somewhere near a 1 second time constant
PWM filter. This may be ok, dont know your application, but it will cause a
noticable lag when adjustments are made.

If you use interleaved PWM a 25 mSec time constant filter would do just
fine = no noticable lag.

To generate 8 bit interleaved PWM, you make an 8 bit reference counter (a
counter that is simply incremented evey interrupt) Then the reference
counter is bit reversed (Bit 7 becomes bit 0, bit 6 becomes bit 1 etc
etc) This is best done with a 256 byte table and the xlat instruction.
Then the individual PWM channels are generated by comparing the PWM value
for the channel with the (bit reversed) reference counter.


Peter Walllace

Steve at fivetrees

unread,
Mar 19, 2006, 1:36:50 PM3/19/06
to
"ScottM" <sc...@mayo.name> wrote in message
news:1142693464.3...@z34g2000cwc.googlegroups.com...
>
> I want to use PC104, because I'm trying to minimize the component count
> and hookup labor, and I need ethernet and 4 serial ports, with the
> possibility of someday adding more serial ports or USB.

As others have noted, TCP/IP might prove a bit awkward with a DOS
environment. Have you considered WinCE? Or a (non-i386, non-PC/104, but with
TCP/IP and multiple serial ports) Rabbit?

Steve
http://www.fivetrees.com


ScottM

unread,
Mar 19, 2006, 6:29:16 PM3/19/06
to
{
unsigned int i;
static unsigned char dm;
static unsigned char v;
static unsigned int x = 37;

puts("With invert and compare:");
for (i = 0; i < 256; ++i)
{
putchar('0' + (bitinv[i] < x)); //compare against inverted bits
if (i % 64 == 63) puts("");
}
puts("");
puts("With add to overflow:");
for (i = 0; i < 256; ++i)
{
__asm {
push EAX
mov EAX, x
add dm, AL //overflow
setc AL
mov v, AL
pop EAX
}
putchar('0' + v);
if (i % 64 == 63) puts("");
}

With invert and compare:
1000100010000000100000001000000010001000100000001000000010000000
1000100010000000100000001000000010000000100000001000000010000000
1000100010000000100000001000000010000000100000001000000010000000
1000100010000000100000001000000010000000100000001000000010000000

With add to overflow:
0000001000000100000010000001000000100000010000001000000100000010
0000010000001000000100000100000010000001000000100000010000001000
0001000000100000010000001000000100000010000010000001000000100000
0100000010000001000000100000010000001000000100000010000001000001

Is the first form what you were proposing? It's got the right number of
bits set, but it's less even; is that really easier to smooth?

Peter Wallace

unread,
Mar 20, 2006, 9:54:45 AM3/20/06
to

OK I didnt think about 'add with overflow' already generating what I would
call interleaved PWM. We use the bit reverse scheme becuse we can trade
off the number of bits that are interleaved with 'straight' PWM to get a
compromise on the ripple frequency versus number of transitions.

Peter Wallace

ScottM

unread,
Mar 22, 2006, 9:09:25 AM3/22/06
to
>Unfortunately, my first day out the the Digital Mars compiler,
> I hit a compiler bug, and I'm wondering if I should use something else.

I wanted to jump in to correct this - my bug, not the compiler's. dmc's
actually has been very well behaved. (I managed to clobber a
compiler-generated jump table. I'll just go slam my fingers in the car
door as penance, now...)

0 new messages