Help. Trying to decide on tools and approaches.

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.

Reply to
ScottM
Loading thread data ...

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.

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.

I hope this is helpful,

Mike Anton

Reply to
Mike Anton

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

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.

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?

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.

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==----

formatting link
The #1 Newsgroup Service in the World! 120,000+ Newsgroups

----= East and West-Coast Server Farms - Total Privacy via Encryption =----

Reply to
Steve Calfee

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.

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

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

Good luck Roman

Reply to
Roman

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

Reply to
Peter Wallace

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.

Reply to
ScottM

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

Reply to
Peter Wallace

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

formatting link

Reply to
Steve at fivetrees

{ 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?

Reply to
ScottM

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

Reply to
Peter Wallace

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...)

Reply to
ScottM

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.