Reply by ScottM March 22, 20062006-03-22
>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...)
Reply by Peter Wallace March 20, 20062006-03-20
On Sun, 19 Mar 2006 15:29:16 -0800, ScottM wrote:

> { > 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?
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 by ScottM March 19, 20062006-03-19
	{
	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 by Steve at fivetrees March 19, 20062006-03-19
"ScottM" <scott@mayo.name> wrote in message 
news:1142693464.399758.153340@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
Reply by Peter Wallace March 19, 20062006-03-19
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
Reply by ScottM March 19, 20062006-03-19
>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.
Reply by Peter Wallace March 18, 20062006-03-18
On Sat, 18 Mar 2006 06:51:04 -0800, ScottM wrote:

> 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.
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 by Roman March 18, 20062006-03-18
<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
Reply by Steve Calfee March 18, 20062006-03-18
On 18 Mar 2006 06:51:04 -0800, "ScottM" <scott@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 =----
Reply by Mike Anton March 18, 20062006-03-18
"ScottM" <scott@mayo.name> wrote in message
news:1142693464.399758.153340@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