Simple Device Driver

I am new to writing CE Drivers and don't know how to get started with the 
following problem.

I have a stable Window CE x86 CEPC platform that I use for various projects. 
It is a headless system (no video, mouse, or keyboard).  It has a network 
port and 2 serial ports. 

 I would like to add a digital I/O board.  The I/O Board is a very simple 
design, it sits on the PC-104(ISA) bus, decodes its address and use the -IOW 
line from the bus to strobe a latch. I can read and write to this board using 
routines derived from DDK_IO like WRITE_PORT_UCHAR for example.

I want to write a large block of data out on this I/O board at about 4MB/s.  
I haven't been able to get this kind of perfomance in user mode.  Other than 
reading the data from a hard disk and then writing it to the I/O board, the 
CPU doesn't have to do much else.  Can I make some sort of TIMER ISR that 
reads data from a buffer filled by an IST and writes it to the device.  The 
IST reads the data from the DISK.

I can modify the board design to have small FIFOs and/or interrupts.

Is there a DRIVER example that would show me how to go about doing this?  Is 
it possible to do a DMA transfer in this scenario?  There doesn't seem to be 
a driver model that fits this kind of scenario.

   I have read a great deal of information about writing drivers and am 
familiar with most of the concepts.  I also have reviewed a few of the sample 
source drivers.  I haven't actually created a driver myself.


Any suggestions would be greatly appreciated!!

0
Utf
3/17/2010 7:41:01 PM
windowsce.platbuilder 744 articles. 0 followers. Follow

11 Replies
1155 Views

Similar Articles

[PageSpeed] 35

I'd say that the driver scheme has almost nothing to do with the problem.  
I'm not sure that you can get that throughput over your PC/104 bus, even if 
you took all of the bus bandwidth.  Isn't the clock 8MHz on PC/104?  That 
means that you'd have to transfer a *byte* every other clock to get 4MBPS.  
I'd say that's crazy, even if you're writing a 16-bit, 2-byte, word on every 
transfer, the maximum for PC/104.

Paul T.

> I am new to writing CE Drivers and don't know how to get started with the 
> following problem.
> 
> I have a stable Window CE x86 CEPC platform that I use for various projects. 
> It is a headless system (no video, mouse, or keyboard).  It has a network 
> port and 2 serial ports. 
> 
>  I would like to add a digital I/O board.  The I/O Board is a very simple 
> design, it sits on the PC-104(ISA) bus, decodes its address and use the -IOW 
> line from the bus to strobe a latch. I can read and write to this board using 
> routines derived from DDK_IO like WRITE_PORT_UCHAR for example.
> 
> I want to write a large block of data out on this I/O board at about 4MB/s.  
> I haven't been able to get this kind of perfomance in user mode.  Other than 
> reading the data from a hard disk and then writing it to the I/O board, the 
> CPU doesn't have to do much else.  Can I make some sort of TIMER ISR that 
> reads data from a buffer filled by an IST and writes it to the device.  The 
> IST reads the data from the DISK.
> 
> I can modify the board design to have small FIFOs and/or interrupts.
> 
> Is there a DRIVER example that would show me how to go about doing this?  Is 
> it possible to do a DMA transfer in this scenario?  There doesn't seem to be 
> a driver model that fits this kind of scenario.
> 
>    I have read a great deal of information about writing drivers and am 
> familiar with most of the concepts.  I also have reviewed a few of the sample 
> source drivers.  I haven't actually created a driver myself.
> 
> 
> Any suggestions would be greatly appreciated!!
> 
0
Utf
3/17/2010 8:56:07 PM
Paul,

    Thanks for the reply.  Your initial analysis is correct.  The 8MHZ ISA 
Bus can only transfer about 2MB/s at 100% capactiy given only an 8bit 
transfer.  Please take a look at the following scenario and let me know if 
there are any other tests that may be worth doing.  Your help would be 
greatly appreciated.


  The ISA Bus on my platform can be set to clock at 8Mhz or 16Mhz.  So if my 
application can survive with a 2MB/s throughput, the 16Mhz clock should be 
able to provide close to 4MB/s.  I would only be using 1/2 of the bus 
capability.  Or a 1/4 if I could switch to 16bit transfers.

  I have a test running like the one below

  unsigned char uc;
  unsigned long x;
  int addr;

  addr = 0x79;
  x=10000000;
  uc=1;
  while(x--)
  {
     __asm
    {
       mov dx, WORD PTR addr
       mov al, uc
       out dx, al
    }
    uc = uc ^ 1;
  }

  This test pulses my output wire 10000000 times.  It should take 5S at 8Mhz 
and 2.5S at 16Mhz.  The strange thing is, when I increased the clock speed 
from 8 Mhz to 16Mhz the pulse widths were not cut in half.   The results were 
at 8Mhz (Total Time: 9s, 800ns Pulse Width or 1.11MB/s) and at 16MHz (6.4S 
600ns or 1.666 MB/s).  

  I was expecting the pulse widths as measured on an osciliscope to be 
closer to 250ns.   What is slowing the pulsing down?   Is it the code loop?   
Is the code being interrupted?   This is running as an application not in 
kernel mode.

  Is it possible to set up a simple DMA transfer test for this???   DMA 
should transfer data hardware to hardware.  I should be able to see the 250ns 
pulses while the transfer is in progress.  Of course there would be some gap 
between the end of one transfer and the begining of the next.

  Any thoughts would be appreciated.

Ken


"Paul G. Tobey [eMVP]" wrote:

> I'd say that the driver scheme has almost nothing to do with the problem.  
> I'm not sure that you can get that throughput over your PC/104 bus, even if 
> you took all of the bus bandwidth.  Isn't the clock 8MHz on PC/104?  That 
> means that you'd have to transfer a *byte* every other clock to get 4MBPS.  
> I'd say that's crazy, even if you're writing a 16-bit, 2-byte, word on every 
> transfer, the maximum for PC/104.
> 
> Paul T.
> 
> > I am new to writing CE Drivers and don't know how to get started with the 
> > following problem.
> > 
> > I have a stable Window CE x86 CEPC platform that I use for various projects. 
> > It is a headless system (no video, mouse, or keyboard).  It has a network 
> > port and 2 serial ports. 
> > 
> >  I would like to add a digital I/O board.  The I/O Board is a very simple 
> > design, it sits on the PC-104(ISA) bus, decodes its address and use the -IOW 
> > line from the bus to strobe a latch. I can read and write to this board using 
> > routines derived from DDK_IO like WRITE_PORT_UCHAR for example.
> > 
> > I want to write a large block of data out on this I/O board at about 4MB/s.  
> > I haven't been able to get this kind of perfomance in user mode.  Other than 
> > reading the data from a hard disk and then writing it to the I/O board, the 
> > CPU doesn't have to do much else.  Can I make some sort of TIMER ISR that 
> > reads data from a buffer filled by an IST and writes it to the device.  The 
> > IST reads the data from the DISK.
> > 
> > I can modify the board design to have small FIFOs and/or interrupts.
> > 
> > Is there a DRIVER example that would show me how to go about doing this?  Is 
> > it possible to do a DMA transfer in this scenario?  There doesn't seem to be 
> > a driver model that fits this kind of scenario.
> > 
> >    I have read a great deal of information about writing drivers and am 
> > familiar with most of the concepts.  I also have reviewed a few of the sample 
> > source drivers.  I haven't actually created a driver myself.
> > 
> > 
> > Any suggestions would be greatly appreciated!!
> > 
0
Utf
3/18/2010 9:14:02 PM
Hi,

The point here may be that your code has to be executed. This implies 
memory reads and writes and this probably slows down the all process. 
You did not tell us too much about your "stable Window CE x86 CEPC 
platform" but depending on its chipset and the way it is tuned (caching, 
etc.), executing your simple loop can take a lot of cycles.
You can try to see what happens when you use outsb instruction instead 
of out:

       __asm
      {
	push si
         mov dx,WORD PTR addr
         mov si,offset buf	; 64KB buffer filled-up with 0,1
	xor cx,cx	; 65536
         rep outsb
	pop si
      }

Of course, using DMA will be the most efficient solution, at least in 
term of raw throughput.

Taking this code into a driver (into the kernel) will not speed-up the 
ISA bus accesses nor the code execution. However, it is generally a good 
idea to put code that access the hardware into device drivers. Even if 
CE 6.0 allows in and out instructions in user code, this will not 
necessarily the case in future versions. And if your hardware becomes 
memory-mapped instead of I/O-mapped (e.g. after switching to a PCI 
architecture), you will have to write a driver to access it.

HTH
Remi


Le 18/03/2010 22:14, knk53 a �crit :
> Paul,
>
>      Thanks for the reply.  Your initial analysis is correct.  The 8MHZ ISA
> Bus can only transfer about 2MB/s at 100% capactiy given only an 8bit
> transfer.  Please take a look at the following scenario and let me know if
> there are any other tests that may be worth doing.  Your help would be
> greatly appreciated.
>
>
>    The ISA Bus on my platform can be set to clock at 8Mhz or 16Mhz.  So if my
> application can survive with a 2MB/s throughput, the 16Mhz clock should be
> able to provide close to 4MB/s.  I would only be using 1/2 of the bus
> capability.  Or a 1/4 if I could switch to 16bit transfers.
>
>    I have a test running like the one below
>
>    unsigned char uc;
>    unsigned long x;
>    int addr;
>
>    addr = 0x79;
>    x=10000000;
>    uc=1;
>    while(x--)
>    {
>       __asm
>      {
>         mov dx, WORD PTR addr
>         mov al, uc
>         out dx, al
>      }
>      uc = uc ^ 1;
>    }
>
>    This test pulses my output wire 10000000 times.  It should take 5S at 8Mhz
> and 2.5S at 16Mhz.  The strange thing is, when I increased the clock speed
> from 8 Mhz to 16Mhz the pulse widths were not cut in half.   The results were
> at 8Mhz (Total Time: 9s, 800ns Pulse Width or 1.11MB/s) and at 16MHz (6.4S
> 600ns or 1.666 MB/s).
>
>    I was expecting the pulse widths as measured on an osciliscope to be
> closer to 250ns.   What is slowing the pulsing down?   Is it the code loop?
> Is the code being interrupted?   This is running as an application not in
> kernel mode.
>
>    Is it possible to set up a simple DMA transfer test for this???   DMA
> should transfer data hardware to hardware.  I should be able to see the 250ns
> pulses while the transfer is in progress.  Of course there would be some gap
> between the end of one transfer and the begining of the next.
>
>    Any thoughts would be appreciated.
>
> Ken
>
>
> "Paul G. Tobey [eMVP]" wrote:
>
>> I'd say that the driver scheme has almost nothing to do with the problem.
>> I'm not sure that you can get that throughput over your PC/104 bus, even if
>> you took all of the bus bandwidth.  Isn't the clock 8MHz on PC/104?  That
>> means that you'd have to transfer a *byte* every other clock to get 4MBPS.
>> I'd say that's crazy, even if you're writing a 16-bit, 2-byte, word on every
>> transfer, the maximum for PC/104.
>>
>> Paul T.
>>
>>> I am new to writing CE Drivers and don't know how to get started with the
>>> following problem.
>>>
>>> I have a stable Window CE x86 CEPC platform that I use for various projects.
>>> It is a headless system (no video, mouse, or keyboard).  It has a network
>>> port and 2 serial ports.
>>>
>>>   I would like to add a digital I/O board.  The I/O Board is a very simple
>>> design, it sits on the PC-104(ISA) bus, decodes its address and use the -IOW
>>> line from the bus to strobe a latch. I can read and write to this board using
>>> routines derived from DDK_IO like WRITE_PORT_UCHAR for example.
>>>
>>> I want to write a large block of data out on this I/O board at about 4MB/s.
>>> I haven't been able to get this kind of perfomance in user mode.  Other than
>>> reading the data from a hard disk and then writing it to the I/O board, the
>>> CPU doesn't have to do much else.  Can I make some sort of TIMER ISR that
>>> reads data from a buffer filled by an IST and writes it to the device.  The
>>> IST reads the data from the DISK.
>>>
>>> I can modify the board design to have small FIFOs and/or interrupts.
>>>
>>> Is there a DRIVER example that would show me how to go about doing this?  Is
>>> it possible to do a DMA transfer in this scenario?  There doesn't seem to be
>>> a driver model that fits this kind of scenario.
>>>
>>>     I have read a great deal of information about writing drivers and am
>>> familiar with most of the concepts.  I also have reviewed a few of the sample
>>> source drivers.  I haven't actually created a driver myself.
>>>
>>>
>>> Any suggestions would be greatly appreciated!!
>>>
0
R
3/19/2010 8:55:11 AM
Remi,

   Thanks for the response.  I will try using the outsb instruction as you 
indicated.  You mention that "Using DMA will be the most efficient solution". 
 Can you recommend a sample I could use to set up a test ?   I would like to 
try and have the DMA write data to this port and see if my pulse lengths get 
closer to what I expect.  

Ken

"R. de Gravelaine" wrote:

> Hi,
> 
> The point here may be that your code has to be executed. This implies 
> memory reads and writes and this probably slows down the all process. 
> You did not tell us too much about your "stable Window CE x86 CEPC 
> platform" but depending on its chipset and the way it is tuned (caching, 
> etc.), executing your simple loop can take a lot of cycles.
> You can try to see what happens when you use outsb instruction instead 
> of out:
> 
>        __asm
>       {
> 	push si
>          mov dx,WORD PTR addr
>          mov si,offset buf	; 64KB buffer filled-up with 0,1
> 	xor cx,cx	; 65536
>          rep outsb
> 	pop si
>       }
> 
> Of course, using DMA will be the most efficient solution, at least in 
> term of raw throughput.
> 
> Taking this code into a driver (into the kernel) will not speed-up the 
> ISA bus accesses nor the code execution. However, it is generally a good 
> idea to put code that access the hardware into device drivers. Even if 
> CE 6.0 allows in and out instructions in user code, this will not 
> necessarily the case in future versions. And if your hardware becomes 
> memory-mapped instead of I/O-mapped (e.g. after switching to a PCI 
> architecture), you will have to write a driver to access it.
> 
> HTH
> Remi
> 
> 
> Le 18/03/2010 22:14, knk53 a écrit :
> > Paul,
> >
> >      Thanks for the reply.  Your initial analysis is correct.  The 8MHZ ISA
> > Bus can only transfer about 2MB/s at 100% capactiy given only an 8bit
> > transfer.  Please take a look at the following scenario and let me know if
> > there are any other tests that may be worth doing.  Your help would be
> > greatly appreciated.
> >
> >
> >    The ISA Bus on my platform can be set to clock at 8Mhz or 16Mhz.  So if my
> > application can survive with a 2MB/s throughput, the 16Mhz clock should be
> > able to provide close to 4MB/s.  I would only be using 1/2 of the bus
> > capability.  Or a 1/4 if I could switch to 16bit transfers.
> >
> >    I have a test running like the one below
> >
> >    unsigned char uc;
> >    unsigned long x;
> >    int addr;
> >
> >    addr = 0x79;
> >    x=10000000;
> >    uc=1;
> >    while(x--)
> >    {
> >       __asm
> >      {
> >         mov dx, WORD PTR addr
> >         mov al, uc
> >         out dx, al
> >      }
> >      uc = uc ^ 1;
> >    }
> >
> >    This test pulses my output wire 10000000 times.  It should take 5S at 8Mhz
> > and 2.5S at 16Mhz.  The strange thing is, when I increased the clock speed
> > from 8 Mhz to 16Mhz the pulse widths were not cut in half.   The results were
> > at 8Mhz (Total Time: 9s, 800ns Pulse Width or 1.11MB/s) and at 16MHz (6.4S
> > 600ns or 1.666 MB/s).
> >
> >    I was expecting the pulse widths as measured on an osciliscope to be
> > closer to 250ns.   What is slowing the pulsing down?   Is it the code loop?
> > Is the code being interrupted?   This is running as an application not in
> > kernel mode.
> >
> >    Is it possible to set up a simple DMA transfer test for this???   DMA
> > should transfer data hardware to hardware.  I should be able to see the 250ns
> > pulses while the transfer is in progress.  Of course there would be some gap
> > between the end of one transfer and the begining of the next.
> >
> >    Any thoughts would be appreciated.
> >
> > Ken
> >
> >
> > "Paul G. Tobey [eMVP]" wrote:
> >
> >> I'd say that the driver scheme has almost nothing to do with the problem.
> >> I'm not sure that you can get that throughput over your PC/104 bus, even if
> >> you took all of the bus bandwidth.  Isn't the clock 8MHz on PC/104?  That
> >> means that you'd have to transfer a *byte* every other clock to get 4MBPS.
> >> I'd say that's crazy, even if you're writing a 16-bit, 2-byte, word on every
> >> transfer, the maximum for PC/104.
> >>
> >> Paul T.
> >>
> >>> I am new to writing CE Drivers and don't know how to get started with the
> >>> following problem.
> >>>
> >>> I have a stable Window CE x86 CEPC platform that I use for various projects.
> >>> It is a headless system (no video, mouse, or keyboard).  It has a network
> >>> port and 2 serial ports.
> >>>
> >>>   I would like to add a digital I/O board.  The I/O Board is a very simple
> >>> design, it sits on the PC-104(ISA) bus, decodes its address and use the -IOW
> >>> line from the bus to strobe a latch. I can read and write to this board using
> >>> routines derived from DDK_IO like WRITE_PORT_UCHAR for example.
> >>>
> >>> I want to write a large block of data out on this I/O board at about 4MB/s.
> >>> I haven't been able to get this kind of perfomance in user mode.  Other than
> >>> reading the data from a hard disk and then writing it to the I/O board, the
> >>> CPU doesn't have to do much else.  Can I make some sort of TIMER ISR that
> >>> reads data from a buffer filled by an IST and writes it to the device.  The
> >>> IST reads the data from the DISK.
> >>>
> >>> I can modify the board design to have small FIFOs and/or interrupts.
> >>>
> >>> Is there a DRIVER example that would show me how to go about doing this?  Is
> >>> it possible to do a DMA transfer in this scenario?  There doesn't seem to be
> >>> a driver model that fits this kind of scenario.
> >>>
> >>>     I have read a great deal of information about writing drivers and am
> >>> familiar with most of the concepts.  I also have reviewed a few of the sample
> >>> source drivers.  I haven't actually created a driver myself.
> >>>
> >>>
> >>> Any suggestions would be greatly appreciated!!
> >>>
> .
> 
0
Utf
3/19/2010 12:34:01 PM
I suppose you are using CE 6.0 (yet another thing you did not tell.)
There is a 8237-based DMA driver available in 
C:\WINCE600\PLATFORM\COMMON\SRC\SOC\X86_MS_V1\DMA8237.
If you feel that this driver is overkill for your problem, you can 
certainly add an extra bunch of x86 instructions to setup a 8237 
memory-to-IO transfer. Here is some code I used in the past to feed a 
sound chip with PCM data (using an 8-bit DMA channel) :

// 8-bits DMA registers (channels 0, 1, 2, 3)
#define DMA_ADDR	(PUCHAR)(g_DmaChan * 2)			// 0,2,4,6
#define DMA_COUNT	(PUCHAR)(g_DmaChan * 2 + 1)		// 1,3,5,7
#define DMA_MASK	(PUCHAR)0x0A
#define DMA_MODE	(PUCHAR)0x0B
#define DMA_FF		(PUCHAR)0x0C
#define DMA_PAGE	(PUCHAR)(c_DmaPage[g_DmaChan])	// 0x87,0x83,0x81,0x82

const DWORD	c_DmaPage[4] = {0x87,0x83,0x81,0x82};	// DMA pages for 
channels 0-3

  - - - - - - - - - - - - - - - - - - - -
// Program the PC DMA for given transfer.
// The PC DMA is programmed to spin around the 2 output buffers.
// The audio chip DMA will be programmed to spin around only 1 buffer,
// interrupting the CPU after each chunk, but still fetching fresh data.
//
#define DMAMODE	0x58	// single, inc, autoinit, read
void StartPcDma()
{
	// Start the PC DMA
#define	ADDRESS	AUDIO_DMA_BUFFER_BASE_PA
#define	COUNT	(AUDIO_DMA_PAGE_SIZE * 2)
	__asm cli
	OUTB(DMA_MASK, g_DmaChan | 4);			// disable DMA while programming
	OUTB(DMA_FF, 0);						// clear the flip-flop
	OUTB(DMA_MODE, g_DmaChan | DMAMODE);	// single, inc, autoinit, read
	OUTB(DMA_COUNT, COUNT - 1);				// LO byte of count
	OUTB(DMA_COUNT, (COUNT - 1) >> 8);		// HI byte of count
	OUTB(DMA_PAGE, ADDRESS >> 16);			// physical page number
	OUTB(DMA_ADDR, ADDRESS);				// LO byte address of buffer
	OUTB(DMA_ADDR, ADDRESS >> 8);			// HI byte address of buffer
	OUTB(DMA_MASK, g_DmaChan);				// done programming the DMA, enable it
	__asm sti
#undef	COUNT
#undef	ADDRESS
} // StartPcDma

Of course, you will need to change the DMAMODE value, to make sure that 
your buffer physical address is below 16 MB (24 bits) and to adapt your 
hardware for the DMA handshaking.

HTH
Remi


Le 19/03/2010 13:34, knk53 a �crit :
> Remi,
>
>     Thanks for the response.  I will try using the outsb instruction as you
> indicated.  You mention that "Using DMA will be the most efficient solution".
>   Can you recommend a sample I could use to set up a test ?   I would like to
> try and have the DMA write data to this port and see if my pulse lengths get
> closer to what I expect.
>
> Ken
>
> "R. de Gravelaine" wrote:
>
>> Hi,
>>
>> The point here may be that your code has to be executed. This implies
>> memory reads and writes and this probably slows down the all process.
>> You did not tell us too much about your "stable Window CE x86 CEPC
>> platform" but depending on its chipset and the way it is tuned (caching,
>> etc.), executing your simple loop can take a lot of cycles.
>> You can try to see what happens when you use outsb instruction instead
>> of out:
>>
>>         __asm
>>        {
>> 	push si
>>           mov dx,WORD PTR addr
>>           mov si,offset buf	; 64KB buffer filled-up with 0,1
>> 	xor cx,cx	; 65536
>>           rep outsb
>> 	pop si
>>        }
>>
>> Of course, using DMA will be the most efficient solution, at least in
>> term of raw throughput.
>>
>> Taking this code into a driver (into the kernel) will not speed-up the
>> ISA bus accesses nor the code execution. However, it is generally a good
>> idea to put code that access the hardware into device drivers. Even if
>> CE 6.0 allows in and out instructions in user code, this will not
>> necessarily the case in future versions. And if your hardware becomes
>> memory-mapped instead of I/O-mapped (e.g. after switching to a PCI
>> architecture), you will have to write a driver to access it.
>>
>> HTH
>> Remi
>>
>>
>> Le 18/03/2010 22:14, knk53 a �crit :
>>> Paul,
>>>
>>>       Thanks for the reply.  Your initial analysis is correct.  The 8MHZ ISA
>>> Bus can only transfer about 2MB/s at 100% capactiy given only an 8bit
>>> transfer.  Please take a look at the following scenario and let me know if
>>> there are any other tests that may be worth doing.  Your help would be
>>> greatly appreciated.
>>>
>>>
>>>     The ISA Bus on my platform can be set to clock at 8Mhz or 16Mhz.  So if my
>>> application can survive with a 2MB/s throughput, the 16Mhz clock should be
>>> able to provide close to 4MB/s.  I would only be using 1/2 of the bus
>>> capability.  Or a 1/4 if I could switch to 16bit transfers.
>>>
>>>     I have a test running like the one below
>>>
>>>     unsigned char uc;
>>>     unsigned long x;
>>>     int addr;
>>>
>>>     addr = 0x79;
>>>     x=10000000;
>>>     uc=1;
>>>     while(x--)
>>>     {
>>>        __asm
>>>       {
>>>          mov dx, WORD PTR addr
>>>          mov al, uc
>>>          out dx, al
>>>       }
>>>       uc = uc ^ 1;
>>>     }
>>>
>>>     This test pulses my output wire 10000000 times.  It should take 5S at 8Mhz
>>> and 2.5S at 16Mhz.  The strange thing is, when I increased the clock speed
>>> from 8 Mhz to 16Mhz the pulse widths were not cut in half.   The results were
>>> at 8Mhz (Total Time: 9s, 800ns Pulse Width or 1.11MB/s) and at 16MHz (6.4S
>>> 600ns or 1.666 MB/s).
>>>
>>>     I was expecting the pulse widths as measured on an osciliscope to be
>>> closer to 250ns.   What is slowing the pulsing down?   Is it the code loop?
>>> Is the code being interrupted?   This is running as an application not in
>>> kernel mode.
>>>
>>>     Is it possible to set up a simple DMA transfer test for this???   DMA
>>> should transfer data hardware to hardware.  I should be able to see the 250ns
>>> pulses while the transfer is in progress.  Of course there would be some gap
>>> between the end of one transfer and the begining of the next.
>>>
>>>     Any thoughts would be appreciated.
>>>
>>> Ken
>>>
>>>
>>> "Paul G. Tobey [eMVP]" wrote:
>>>
>>>> I'd say that the driver scheme has almost nothing to do with the problem.
>>>> I'm not sure that you can get that throughput over your PC/104 bus, even if
>>>> you took all of the bus bandwidth.  Isn't the clock 8MHz on PC/104?  That
>>>> means that you'd have to transfer a *byte* every other clock to get 4MBPS.
>>>> I'd say that's crazy, even if you're writing a 16-bit, 2-byte, word on every
>>>> transfer, the maximum for PC/104.
>>>>
>>>> Paul T.
>>>>
>>>>> I am new to writing CE Drivers and don't know how to get started with the
>>>>> following problem.
>>>>>
>>>>> I have a stable Window CE x86 CEPC platform that I use for various projects.
>>>>> It is a headless system (no video, mouse, or keyboard).  It has a network
>>>>> port and 2 serial ports.
>>>>>
>>>>>    I would like to add a digital I/O board.  The I/O Board is a very simple
>>>>> design, it sits on the PC-104(ISA) bus, decodes its address and use the -IOW
>>>>> line from the bus to strobe a latch. I can read and write to this board using
>>>>> routines derived from DDK_IO like WRITE_PORT_UCHAR for example.
>>>>>
>>>>> I want to write a large block of data out on this I/O board at about 4MB/s.
>>>>> I haven't been able to get this kind of perfomance in user mode.  Other than
>>>>> reading the data from a hard disk and then writing it to the I/O board, the
>>>>> CPU doesn't have to do much else.  Can I make some sort of TIMER ISR that
>>>>> reads data from a buffer filled by an IST and writes it to the device.  The
>>>>> IST reads the data from the DISK.
>>>>>
>>>>> I can modify the board design to have small FIFOs and/or interrupts.
>>>>>
>>>>> Is there a DRIVER example that would show me how to go about doing this?  Is
>>>>> it possible to do a DMA transfer in this scenario?  There doesn't seem to be
>>>>> a driver model that fits this kind of scenario.
>>>>>
>>>>>      I have read a great deal of information about writing drivers and am
>>>>> familiar with most of the concepts.  I also have reviewed a few of the sample
>>>>> source drivers.  I haven't actually created a driver myself.
>>>>>
>>>>>
>>>>> Any suggestions would be greatly appreciated!!
>>>>>
>> .
>>
0
R
3/19/2010 1:50:46 PM
Remi,

    Thanks for the info.  I am using CE 5.0.  It looks like the DMA8237 
driver is not in my directory tree.  I will review the sample code you posted 
and see if I can use that to test my board.  Is there a sample in CE 5.0??

   For future reference, is there a standard way to convey the platform 
paramters when posting a question on these message boards?

Thanks again

Ken

"R. de Gravelaine" wrote:

> I suppose you are using CE 6.0 (yet another thing you did not tell.)
> There is a 8237-based DMA driver available in 
> C:\WINCE600\PLATFORM\COMMON\SRC\SOC\X86_MS_V1\DMA8237.
> If you feel that this driver is overkill for your problem, you can 
> certainly add an extra bunch of x86 instructions to setup a 8237 
> memory-to-IO transfer. Here is some code I used in the past to feed a 
> sound chip with PCM data (using an 8-bit DMA channel) :
> 
> // 8-bits DMA registers (channels 0, 1, 2, 3)
> #define DMA_ADDR	(PUCHAR)(g_DmaChan * 2)			// 0,2,4,6
> #define DMA_COUNT	(PUCHAR)(g_DmaChan * 2 + 1)		// 1,3,5,7
> #define DMA_MASK	(PUCHAR)0x0A
> #define DMA_MODE	(PUCHAR)0x0B
> #define DMA_FF		(PUCHAR)0x0C
> #define DMA_PAGE	(PUCHAR)(c_DmaPage[g_DmaChan])	// 0x87,0x83,0x81,0x82
> 
> const DWORD	c_DmaPage[4] = {0x87,0x83,0x81,0x82};	// DMA pages for 
> channels 0-3
> 
>   - - - - - - - - - - - - - - - - - - - -
> // Program the PC DMA for given transfer.
> // The PC DMA is programmed to spin around the 2 output buffers.
> // The audio chip DMA will be programmed to spin around only 1 buffer,
> // interrupting the CPU after each chunk, but still fetching fresh data.
> //
> #define DMAMODE	0x58	// single, inc, autoinit, read
> void StartPcDma()
> {
> 	// Start the PC DMA
> #define	ADDRESS	AUDIO_DMA_BUFFER_BASE_PA
> #define	COUNT	(AUDIO_DMA_PAGE_SIZE * 2)
> 	__asm cli
> 	OUTB(DMA_MASK, g_DmaChan | 4);			// disable DMA while programming
> 	OUTB(DMA_FF, 0);						// clear the flip-flop
> 	OUTB(DMA_MODE, g_DmaChan | DMAMODE);	// single, inc, autoinit, read
> 	OUTB(DMA_COUNT, COUNT - 1);				// LO byte of count
> 	OUTB(DMA_COUNT, (COUNT - 1) >> 8);		// HI byte of count
> 	OUTB(DMA_PAGE, ADDRESS >> 16);			// physical page number
> 	OUTB(DMA_ADDR, ADDRESS);				// LO byte address of buffer
> 	OUTB(DMA_ADDR, ADDRESS >> 8);			// HI byte address of buffer
> 	OUTB(DMA_MASK, g_DmaChan);				// done programming the DMA, enable it
> 	__asm sti
> #undef	COUNT
> #undef	ADDRESS
> } // StartPcDma
> 
> Of course, you will need to change the DMAMODE value, to make sure that 
> your buffer physical address is below 16 MB (24 bits) and to adapt your 
> hardware for the DMA handshaking.
> 
> HTH
> Remi
> 
> 
> Le 19/03/2010 13:34, knk53 a écrit :
> > Remi,
> >
> >     Thanks for the response.  I will try using the outsb instruction as you
> > indicated.  You mention that "Using DMA will be the most efficient solution".
> >   Can you recommend a sample I could use to set up a test ?   I would like to
> > try and have the DMA write data to this port and see if my pulse lengths get
> > closer to what I expect.
> >
> > Ken
> >
> > "R. de Gravelaine" wrote:
> >
> >> Hi,
> >>
> >> The point here may be that your code has to be executed. This implies
> >> memory reads and writes and this probably slows down the all process.
> >> You did not tell us too much about your "stable Window CE x86 CEPC
> >> platform" but depending on its chipset and the way it is tuned (caching,
> >> etc.), executing your simple loop can take a lot of cycles.
> >> You can try to see what happens when you use outsb instruction instead
> >> of out:
> >>
> >>         __asm
> >>        {
> >> 	push si
> >>           mov dx,WORD PTR addr
> >>           mov si,offset buf	; 64KB buffer filled-up with 0,1
> >> 	xor cx,cx	; 65536
> >>           rep outsb
> >> 	pop si
> >>        }
> >>
> >> Of course, using DMA will be the most efficient solution, at least in
> >> term of raw throughput.
> >>
> >> Taking this code into a driver (into the kernel) will not speed-up the
> >> ISA bus accesses nor the code execution. However, it is generally a good
> >> idea to put code that access the hardware into device drivers. Even if
> >> CE 6.0 allows in and out instructions in user code, this will not
> >> necessarily the case in future versions. And if your hardware becomes
> >> memory-mapped instead of I/O-mapped (e.g. after switching to a PCI
> >> architecture), you will have to write a driver to access it.
> >>
> >> HTH
> >> Remi
> >>
> >>
> >> Le 18/03/2010 22:14, knk53 a écrit :
> >>> Paul,
> >>>
> >>>       Thanks for the reply.  Your initial analysis is correct.  The 8MHZ ISA
> >>> Bus can only transfer about 2MB/s at 100% capactiy given only an 8bit
> >>> transfer.  Please take a look at the following scenario and let me know if
> >>> there are any other tests that may be worth doing.  Your help would be
> >>> greatly appreciated.
> >>>
> >>>
> >>>     The ISA Bus on my platform can be set to clock at 8Mhz or 16Mhz.  So if my
> >>> application can survive with a 2MB/s throughput, the 16Mhz clock should be
> >>> able to provide close to 4MB/s.  I would only be using 1/2 of the bus
> >>> capability.  Or a 1/4 if I could switch to 16bit transfers.
> >>>
> >>>     I have a test running like the one below
> >>>
> >>>     unsigned char uc;
> >>>     unsigned long x;
> >>>     int addr;
> >>>
> >>>     addr = 0x79;
> >>>     x=10000000;
> >>>     uc=1;
> >>>     while(x--)
> >>>     {
> >>>        __asm
> >>>       {
> >>>          mov dx, WORD PTR addr
> >>>          mov al, uc
> >>>          out dx, al
> >>>       }
> >>>       uc = uc ^ 1;
> >>>     }
> >>>
> >>>     This test pulses my output wire 10000000 times.  It should take 5S at 8Mhz
> >>> and 2.5S at 16Mhz.  The strange thing is, when I increased the clock speed
> >>> from 8 Mhz to 16Mhz the pulse widths were not cut in half.   The results were
> >>> at 8Mhz (Total Time: 9s, 800ns Pulse Width or 1.11MB/s) and at 16MHz (6.4S
> >>> 600ns or 1.666 MB/s).
> >>>
> >>>     I was expecting the pulse widths as measured on an osciliscope to be
> >>> closer to 250ns.   What is slowing the pulsing down?   Is it the code loop?
> >>> Is the code being interrupted?   This is running as an application not in
> >>> kernel mode.
> >>>
> >>>     Is it possible to set up a simple DMA transfer test for this???   DMA
> >>> should transfer data hardware to hardware.  I should be able to see the 250ns
> >>> pulses while the transfer is in progress.  Of course there would be some gap
> >>> between the end of one transfer and the begining of the next.
> >>>
> >>>     Any thoughts would be appreciated.
> >>>
> >>> Ken
> >>>
> >>>
> >>> "Paul G. Tobey [eMVP]" wrote:
> >>>
> >>>> I'd say that the driver scheme has almost nothing to do with the problem.
> >>>> I'm not sure that you can get that throughput over your PC/104 bus, even if
> >>>> you took all of the bus bandwidth.  Isn't the clock 8MHz on PC/104?  That
> >>>> means that you'd have to transfer a *byte* every other clock to get 4MBPS.
> >>>> I'd say that's crazy, even if you're writing a 16-bit, 2-byte, word on every
> >>>> transfer, the maximum for PC/104.
> >>>>
> >>>> Paul T.
> >>>>
> >>>>> I am new to writing CE Drivers and don't know how to get started with the
> >>>>> following problem.
> >>>>>
> >>>>> I have a stable Window CE x86 CEPC platform that I use for various projects.
> >>>>> It is a headless system (no video, mouse, or keyboard).  It has a network
> >>>>> port and 2 serial ports.
> >>>>>
> >>>>>    I would like to add a digital I/O board.  The I/O Board is a very simple
> >>>>> design, it sits on the PC-104(ISA) bus, decodes its address and use the -IOW
> >>>>> line from the bus to strobe a latch. I can read and write to this board using
> >>>>> routines derived from DDK_IO like WRITE_PORT_UCHAR for example.
> >>>>>
> >>>>> I want to write a large block of data out on this I/O board at about 4MB/s.
> >>>>> I haven't been able to get this kind of perfomance in user mode.  Other than
> >>>>> reading the data from a hard disk and then writing it to the I/O board, the
> >>>>> CPU doesn't have to do much else.  Can I make some sort of TIMER ISR that
> >>>>> reads data from a buffer filled by an IST and writes it to the device.  The
> >>>>> IST reads the data from the DISK.
> >>>>>
> >>>>> I can modify the board design to have small FIFOs and/or interrupts.
> >>>>>
> >>>>> Is there a DRIVER example that would show me how to go about doing this?  Is
> >>>>> it possible to do a DMA transfer in this scenario?  There doesn't seem to be
> >>>>> a driver model that fits this kind of scenario.
> >>>>>
> >>>>>      I have read a great deal of information about writing drivers and am
> >>>>> familiar with most of the concepts.  I also have reviewed a few of the sample
> >>>>> source drivers.  I haven't actually created a driver myself.
> >>>>>
> >>>>>
> >>>>> Any suggestions would be greatly appreciated!!
> >>>>>
> >> .
> >>
> .
> 
0
Utf
3/19/2010 6:19:03 PM
Hi Ken,

I am afraid there was not such 8237 driver sample before CE 6.0.
Anyway, the code in this driver is really bloated compared to your 
needs, so you'd probably better go on your own and write-down a few out 
instructions to start and stop a DMA transfer.
If not already done, read the 8237 (of equivalent) documentation and try 
to figure out how to use it, at both the hardware and software levels.
Also, remember that the "rep outsb" (or even better "rep outsw") test 
can show you what is feasible of not. If you are able to efficiently 
stuff your hardware through a "rep outs" instruction, you'll probably 
not need to switch to DMA. It is up to you.

AFAIK, there is no standard way to convey your platform parameters to 
this newsgroup, even if I think that Bruce Eitman (?) wrote something on 
his blog related to this topic (posting to CE newsgroup.)

Remi


Le 19/03/2010 19:19, knk53 a �crit :
> Remi,
>
>      Thanks for the info.  I am using CE 5.0.  It looks like the DMA8237
> driver is not in my directory tree.  I will review the sample code you posted
> and see if I can use that to test my board.  Is there a sample in CE 5.0??
>
>     For future reference, is there a standard way to convey the platform
> paramters when posting a question on these message boards?
>
> Thanks again
>
> Ken
>
> "R. de Gravelaine" wrote:
>
>> I suppose you are using CE 6.0 (yet another thing you did not tell.)
>> There is a 8237-based DMA driver available in
>> C:\WINCE600\PLATFORM\COMMON\SRC\SOC\X86_MS_V1\DMA8237.
>> If you feel that this driver is overkill for your problem, you can
>> certainly add an extra bunch of x86 instructions to setup a 8237
>> memory-to-IO transfer. Here is some code I used in the past to feed a
>> sound chip with PCM data (using an 8-bit DMA channel) :
>>
>> // 8-bits DMA registers (channels 0, 1, 2, 3)
>> #define DMA_ADDR	(PUCHAR)(g_DmaChan * 2)			// 0,2,4,6
>> #define DMA_COUNT	(PUCHAR)(g_DmaChan * 2 + 1)		// 1,3,5,7
>> #define DMA_MASK	(PUCHAR)0x0A
>> #define DMA_MODE	(PUCHAR)0x0B
>> #define DMA_FF		(PUCHAR)0x0C
>> #define DMA_PAGE	(PUCHAR)(c_DmaPage[g_DmaChan])	// 0x87,0x83,0x81,0x82
>>
>> const DWORD	c_DmaPage[4] = {0x87,0x83,0x81,0x82};	// DMA pages for
>> channels 0-3
>>
>>    - - - - - - - - - - - - - - - - - - - -
>> // Program the PC DMA for given transfer.
>> // The PC DMA is programmed to spin around the 2 output buffers.
>> // The audio chip DMA will be programmed to spin around only 1 buffer,
>> // interrupting the CPU after each chunk, but still fetching fresh data.
>> //
>> #define DMAMODE	0x58	// single, inc, autoinit, read
>> void StartPcDma()
>> {
>> 	// Start the PC DMA
>> #define	ADDRESS	AUDIO_DMA_BUFFER_BASE_PA
>> #define	COUNT	(AUDIO_DMA_PAGE_SIZE * 2)
>> 	__asm cli
>> 	OUTB(DMA_MASK, g_DmaChan | 4);			// disable DMA while programming
>> 	OUTB(DMA_FF, 0);						// clear the flip-flop
>> 	OUTB(DMA_MODE, g_DmaChan | DMAMODE);	// single, inc, autoinit, read
>> 	OUTB(DMA_COUNT, COUNT - 1);				// LO byte of count
>> 	OUTB(DMA_COUNT, (COUNT - 1)>>  8);		// HI byte of count
>> 	OUTB(DMA_PAGE, ADDRESS>>  16);			// physical page number
>> 	OUTB(DMA_ADDR, ADDRESS);				// LO byte address of buffer
>> 	OUTB(DMA_ADDR, ADDRESS>>  8);			// HI byte address of buffer
>> 	OUTB(DMA_MASK, g_DmaChan);				// done programming the DMA, enable it
>> 	__asm sti
>> #undef	COUNT
>> #undef	ADDRESS
>> } // StartPcDma
>>
>> Of course, you will need to change the DMAMODE value, to make sure that
>> your buffer physical address is below 16 MB (24 bits) and to adapt your
>> hardware for the DMA handshaking.
>>
>> HTH
>> Remi
>>
>>
>> Le 19/03/2010 13:34, knk53 a �crit :
>>> Remi,
>>>
>>>      Thanks for the response.  I will try using the outsb instruction as you
>>> indicated.  You mention that "Using DMA will be the most efficient solution".
>>>    Can you recommend a sample I could use to set up a test ?   I would like to
>>> try and have the DMA write data to this port and see if my pulse lengths get
>>> closer to what I expect.
>>>
>>> Ken
>>>
>>> "R. de Gravelaine" wrote:
>>>
>>>> Hi,
>>>>
>>>> The point here may be that your code has to be executed. This implies
>>>> memory reads and writes and this probably slows down the all process.
>>>> You did not tell us too much about your "stable Window CE x86 CEPC
>>>> platform" but depending on its chipset and the way it is tuned (caching,
>>>> etc.), executing your simple loop can take a lot of cycles.
>>>> You can try to see what happens when you use outsb instruction instead
>>>> of out:
>>>>
>>>>          __asm
>>>>         {
>>>> 	push si
>>>>            mov dx,WORD PTR addr
>>>>            mov si,offset buf	; 64KB buffer filled-up with 0,1
>>>> 	xor cx,cx	; 65536
>>>>            rep outsb
>>>> 	pop si
>>>>         }
>>>>
>>>> Of course, using DMA will be the most efficient solution, at least in
>>>> term of raw throughput.
>>>>
>>>> Taking this code into a driver (into the kernel) will not speed-up the
>>>> ISA bus accesses nor the code execution. However, it is generally a good
>>>> idea to put code that access the hardware into device drivers. Even if
>>>> CE 6.0 allows in and out instructions in user code, this will not
>>>> necessarily the case in future versions. And if your hardware becomes
>>>> memory-mapped instead of I/O-mapped (e.g. after switching to a PCI
>>>> architecture), you will have to write a driver to access it.
>>>>
>>>> HTH
>>>> Remi
>>>>
>>>>
>>>> Le 18/03/2010 22:14, knk53 a �crit :
>>>>> Paul,
>>>>>
>>>>>        Thanks for the reply.  Your initial analysis is correct.  The 8MHZ ISA
>>>>> Bus can only transfer about 2MB/s at 100% capactiy given only an 8bit
>>>>> transfer.  Please take a look at the following scenario and let me know if
>>>>> there are any other tests that may be worth doing.  Your help would be
>>>>> greatly appreciated.
>>>>>
>>>>>
>>>>>      The ISA Bus on my platform can be set to clock at 8Mhz or 16Mhz.  So if my
>>>>> application can survive with a 2MB/s throughput, the 16Mhz clock should be
>>>>> able to provide close to 4MB/s.  I would only be using 1/2 of the bus
>>>>> capability.  Or a 1/4 if I could switch to 16bit transfers.
>>>>>
>>>>>      I have a test running like the one below
>>>>>
>>>>>      unsigned char uc;
>>>>>      unsigned long x;
>>>>>      int addr;
>>>>>
>>>>>      addr = 0x79;
>>>>>      x=10000000;
>>>>>      uc=1;
>>>>>      while(x--)
>>>>>      {
>>>>>         __asm
>>>>>        {
>>>>>           mov dx, WORD PTR addr
>>>>>           mov al, uc
>>>>>           out dx, al
>>>>>        }
>>>>>        uc = uc ^ 1;
>>>>>      }
>>>>>
>>>>>      This test pulses my output wire 10000000 times.  It should take 5S at 8Mhz
>>>>> and 2.5S at 16Mhz.  The strange thing is, when I increased the clock speed
>>>>> from 8 Mhz to 16Mhz the pulse widths were not cut in half.   The results were
>>>>> at 8Mhz (Total Time: 9s, 800ns Pulse Width or 1.11MB/s) and at 16MHz (6.4S
>>>>> 600ns or 1.666 MB/s).
>>>>>
>>>>>      I was expecting the pulse widths as measured on an osciliscope to be
>>>>> closer to 250ns.   What is slowing the pulsing down?   Is it the code loop?
>>>>> Is the code being interrupted?   This is running as an application not in
>>>>> kernel mode.
>>>>>
>>>>>      Is it possible to set up a simple DMA transfer test for this???   DMA
>>>>> should transfer data hardware to hardware.  I should be able to see the 250ns
>>>>> pulses while the transfer is in progress.  Of course there would be some gap
>>>>> between the end of one transfer and the begining of the next.
>>>>>
>>>>>      Any thoughts would be appreciated.
>>>>>
>>>>> Ken
>>>>>
>>>>>
>>>>> "Paul G. Tobey [eMVP]" wrote:
>>>>>
>>>>>> I'd say that the driver scheme has almost nothing to do with the problem.
>>>>>> I'm not sure that you can get that throughput over your PC/104 bus, even if
>>>>>> you took all of the bus bandwidth.  Isn't the clock 8MHz on PC/104?  That
>>>>>> means that you'd have to transfer a *byte* every other clock to get 4MBPS.
>>>>>> I'd say that's crazy, even if you're writing a 16-bit, 2-byte, word on every
>>>>>> transfer, the maximum for PC/104.
>>>>>>
>>>>>> Paul T.
>>>>>>
>>>>>>> I am new to writing CE Drivers and don't know how to get started with the
>>>>>>> following problem.
>>>>>>>
>>>>>>> I have a stable Window CE x86 CEPC platform that I use for various projects.
>>>>>>> It is a headless system (no video, mouse, or keyboard).  It has a network
>>>>>>> port and 2 serial ports.
>>>>>>>
>>>>>>>     I would like to add a digital I/O board.  The I/O Board is a very simple
>>>>>>> design, it sits on the PC-104(ISA) bus, decodes its address and use the -IOW
>>>>>>> line from the bus to strobe a latch. I can read and write to this board using
>>>>>>> routines derived from DDK_IO like WRITE_PORT_UCHAR for example.
>>>>>>>
>>>>>>> I want to write a large block of data out on this I/O board at about 4MB/s.
>>>>>>> I haven't been able to get this kind of perfomance in user mode.  Other than
>>>>>>> reading the data from a hard disk and then writing it to the I/O board, the
>>>>>>> CPU doesn't have to do much else.  Can I make some sort of TIMER ISR that
>>>>>>> reads data from a buffer filled by an IST and writes it to the device.  The
>>>>>>> IST reads the data from the DISK.
>>>>>>>
>>>>>>> I can modify the board design to have small FIFOs and/or interrupts.
>>>>>>>
>>>>>>> Is there a DRIVER example that would show me how to go about doing this?  Is
>>>>>>> it possible to do a DMA transfer in this scenario?  There doesn't seem to be
>>>>>>> a driver model that fits this kind of scenario.
>>>>>>>
>>>>>>>       I have read a great deal of information about writing drivers and am
>>>>>>> familiar with most of the concepts.  I also have reviewed a few of the sample
>>>>>>> source drivers.  I haven't actually created a driver myself.
>>>>>>>
>>>>>>>
>>>>>>> Any suggestions would be greatly appreciated!!
>>>>>>>
>>>> .
>>>>
>> .
>>
0
R
3/21/2010 3:17:59 PM
Remi,

  Thanks again for responses.   My understanding of these concepts is 
greatly improving.  

   I had a couple of questions about using the DMA method

   Our Board has an 8237 DMA Controller 
   The DMA controller is at address 00H - 0FH  (Seems similar to your example)
   The DMA Page Register is at 80H - 8FH

   I need to allocate a buffer to hold the data that I want to transfer.  Do 
I use VirtualAlloc() and VirtualCopy() to create the buffer and map it to 
physical memory?  Or can I use LocalAlloc() to get the buffer?  

The DMA controller needs a physical address, correct?

*******************

  You defined your page registers as follows:
const DWORD	c_DmaPage[4] = {0x87,0x83,0x81,0x82};

  Is this a standard mapping?  Where do I find this information?   Is that 
assigned in the registry somewhere??  The information for my processor board 
only says that  the DMA Page Register is at 80H - 8FH.  Not which channel is 
which??




Thanks for all the help

Ken



"R. de Gravelaine" wrote:

> Hi Ken,
> 
> I am afraid there was not such 8237 driver sample before CE 6.0.
> Anyway, the code in this driver is really bloated compared to your 
> needs, so you'd probably better go on your own and write-down a few out 
> instructions to start and stop a DMA transfer.
> If not already done, read the 8237 (of equivalent) documentation and try 
> to figure out how to use it, at both the hardware and software levels.
> Also, remember that the "rep outsb" (or even better "rep outsw") test 
> can show you what is feasible of not. If you are able to efficiently 
> stuff your hardware through a "rep outs" instruction, you'll probably 
> not need to switch to DMA. It is up to you.
> 
> AFAIK, there is no standard way to convey your platform parameters to 
> this newsgroup, even if I think that Bruce Eitman (?) wrote something on 
> his blog related to this topic (posting to CE newsgroup.)
> 
> Remi
> 
> 
> Le 19/03/2010 19:19, knk53 a écrit :
> > Remi,
> >
> >      Thanks for the info.  I am using CE 5.0.  It looks like the DMA8237
> > driver is not in my directory tree.  I will review the sample code you posted
> > and see if I can use that to test my board.  Is there a sample in CE 5.0??
> >
> >     For future reference, is there a standard way to convey the platform
> > paramters when posting a question on these message boards?
> >
> > Thanks again
> >
> > Ken
> >
> > "R. de Gravelaine" wrote:
> >
> >> I suppose you are using CE 6.0 (yet another thing you did not tell.)
> >> There is a 8237-based DMA driver available in
> >> C:\WINCE600\PLATFORM\COMMON\SRC\SOC\X86_MS_V1\DMA8237.
> >> If you feel that this driver is overkill for your problem, you can
> >> certainly add an extra bunch of x86 instructions to setup a 8237
> >> memory-to-IO transfer. Here is some code I used in the past to feed a
> >> sound chip with PCM data (using an 8-bit DMA channel) :
> >>
> >> // 8-bits DMA registers (channels 0, 1, 2, 3)
> >> #define DMA_ADDR	(PUCHAR)(g_DmaChan * 2)			// 0,2,4,6
> >> #define DMA_COUNT	(PUCHAR)(g_DmaChan * 2 + 1)		// 1,3,5,7
> >> #define DMA_MASK	(PUCHAR)0x0A
> >> #define DMA_MODE	(PUCHAR)0x0B
> >> #define DMA_FF		(PUCHAR)0x0C
> >> #define DMA_PAGE	(PUCHAR)(c_DmaPage[g_DmaChan])	// 0x87,0x83,0x81,0x82
> >>
> >> const DWORD	c_DmaPage[4] = {0x87,0x83,0x81,0x82};	// DMA pages for
> >> channels 0-3
> >>
> >>    - - - - - - - - - - - - - - - - - - - -
> >> // Program the PC DMA for given transfer.
> >> // The PC DMA is programmed to spin around the 2 output buffers.
> >> // The audio chip DMA will be programmed to spin around only 1 buffer,
> >> // interrupting the CPU after each chunk, but still fetching fresh data.
> >> //
> >> #define DMAMODE	0x58	// single, inc, autoinit, read
> >> void StartPcDma()
> >> {
> >> 	// Start the PC DMA
> >> #define	ADDRESS	AUDIO_DMA_BUFFER_BASE_PA
> >> #define	COUNT	(AUDIO_DMA_PAGE_SIZE * 2)
> >> 	__asm cli
> >> 	OUTB(DMA_MASK, g_DmaChan | 4);			// disable DMA while programming
> >> 	OUTB(DMA_FF, 0);						// clear the flip-flop
> >> 	OUTB(DMA_MODE, g_DmaChan | DMAMODE);	// single, inc, autoinit, read
> >> 	OUTB(DMA_COUNT, COUNT - 1);				// LO byte of count
> >> 	OUTB(DMA_COUNT, (COUNT - 1)>>  8);		// HI byte of count
> >> 	OUTB(DMA_PAGE, ADDRESS>>  16);			// physical page number
> >> 	OUTB(DMA_ADDR, ADDRESS);				// LO byte address of buffer
> >> 	OUTB(DMA_ADDR, ADDRESS>>  8);			// HI byte address of buffer
> >> 	OUTB(DMA_MASK, g_DmaChan);				// done programming the DMA, enable it
> >> 	__asm sti
> >> #undef	COUNT
> >> #undef	ADDRESS
> >> } // StartPcDma
> >>
> >> Of course, you will need to change the DMAMODE value, to make sure that
> >> your buffer physical address is below 16 MB (24 bits) and to adapt your
> >> hardware for the DMA handshaking.
> >>
> >> HTH
> >> Remi
> >>
> >>
> >> Le 19/03/2010 13:34, knk53 a écrit :
> >>> Remi,
> >>>
> >>>      Thanks for the response.  I will try using the outsb instruction as you
> >>> indicated.  You mention that "Using DMA will be the most efficient solution".
> >>>    Can you recommend a sample I could use to set up a test ?   I would like to
> >>> try and have the DMA write data to this port and see if my pulse lengths get
> >>> closer to what I expect.
> >>>
> >>> Ken
> >>>
> >>> "R. de Gravelaine" wrote:
> >>>
> >>>> Hi,
> >>>>
> >>>> The point here may be that your code has to be executed. This implies
> >>>> memory reads and writes and this probably slows down the all process.
> >>>> You did not tell us too much about your "stable Window CE x86 CEPC
> >>>> platform" but depending on its chipset and the way it is tuned (caching,
> >>>> etc.), executing your simple loop can take a lot of cycles.
> >>>> You can try to see what happens when you use outsb instruction instead
> >>>> of out:
> >>>>
> >>>>          __asm
> >>>>         {
> >>>> 	push si
> >>>>            mov dx,WORD PTR addr
> >>>>            mov si,offset buf	; 64KB buffer filled-up with 0,1
> >>>> 	xor cx,cx	; 65536
> >>>>            rep outsb
> >>>> 	pop si
> >>>>         }
> >>>>
> >>>> Of course, using DMA will be the most efficient solution, at least in
> >>>> term of raw throughput.
> >>>>
> >>>> Taking this code into a driver (into the kernel) will not speed-up the
> >>>> ISA bus accesses nor the code execution. However, it is generally a good
> >>>> idea to put code that access the hardware into device drivers. Even if
> >>>> CE 6.0 allows in and out instructions in user code, this will not
> >>>> necessarily the case in future versions. And if your hardware becomes
> >>>> memory-mapped instead of I/O-mapped (e.g. after switching to a PCI
> >>>> architecture), you will have to write a driver to access it.
> >>>>
> >>>> HTH
> >>>> Remi
> >>>>
> >>>>
> >>>> Le 18/03/2010 22:14, knk53 a écrit :
> >>>>> Paul,
> >>>>>
> >>>>>        Thanks for the reply.  Your initial analysis is correct.  The 8MHZ ISA
> >>>>> Bus can only transfer about 2MB/s at 100% capactiy given only an 8bit
> >>>>> transfer.  Please take a look at the following scenario and let me know if
> >>>>> there are any other tests that may be worth doing.  Your help would be
> >>>>> greatly appreciated.
> >>>>>
> >>>>>
> >>>>>      The ISA Bus on my platform can be set to clock at 8Mhz or 16Mhz.  So if my
> >>>>> application can survive with a 2MB/s throughput, the 16Mhz clock should be
> >>>>> able to provide close to 4MB/s.  I would only be using 1/2 of the bus
> >>>>> capability.  Or a 1/4 if I could switch to 16bit transfers.
> >>>>>
> >>>>>      I have a test running like the one below
> >>>>>
> >>>>>      unsigned char uc;
> >>>>>      unsigned long x;
> >>>>>      int addr;
> >>>>>
> >>>>>      addr = 0x79;
> >>>>>      x=10000000;
> >>>>>      uc=1;
> >>>>>      while(x--)
> >>>>>      {
> >>>>>         __asm
> >>>>>        {
> >>>>>           mov dx, WORD PTR addr
> >>>>>           mov al, uc
> >>>>>           out dx, al
> >>>>>        }
> >>>>>        uc = uc ^ 1;
> >>>>>      }
> >>>>>
> >>>>>      This test pulses my output wire 10000000 times.  It should take 5S at 8Mhz
> >>>>> and 2.5S at 16Mhz.  The strange thing is, when I increased the clock speed
> >>>>> from 8 Mhz to 16Mhz the pulse widths were not cut in half.   The results were
> >>>>> at 8Mhz (Total Time: 9s, 800ns Pulse Width or 1.11MB/s) and at 16MHz (6.4S
> >>>>> 600ns or 1.666 MB/s).
> >>>>>
> >>>>>      I was expecting the pulse widths as measured on an osciliscope to be
> >>>>> closer to 250ns.   What is slowing the pulsing down?   Is it the code loop?
> >>>>> Is the code being interrupted?   This is running as an application not in
> >>>>> kernel mode.
> >>>>>
> >>>>>      Is it possible to set up a simple DMA transfer test for this???   DMA
> >>>>> should transfer data hardware to hardware.  I should be able to see the 250ns
> >>>>> pulses while the transfer is in progress.  Of course there would be some gap
> >>>>> between the end of one transfer and the begining of the next.
> >>>>>
> >>>>>      Any thoughts would be appreciated.
> >>>>>
> >>>>> Ken
> >>>>>
> >>>>>
> >>>>> "Paul G. Tobey [eMVP]" wrote:
> >>>>>
> >>>>>> I'd say that the driver scheme has almost nothing to do with the problem.
> >>>>>> I'm not sure that you can get that throughput over your PC/104 bus, even if
> >>>>>> you took all of the bus bandwidth.  Isn't the clock 8MHz on PC/104?  That
> >>>>>> means that you'd have to transfer a *byte* every other clock to get 4MBPS.
> >>>>>> I'd say that's crazy, even if you're writing a 16-bit, 2-byte, word on every
> >>>>>> transfer, the maximum for PC/104.
> >>>>>>
> >>>>>> Paul T.
> >>>>>>
> >>>>>>> I am new to writing CE Drivers and don't know how to get started with the
> >>>>>>> following problem.
> >>>>>>>
> >>>>>>> I have a stable Window CE x86 CEPC platform that I use for various projects.
> >>>>>>> It is a headless system (no video, mouse, or keyboard).  It has a network
> >>>>>>> port and 2 serial ports.
> >>>>>>>
> >>>>>>>     I would like to add a digital I/O board.  The I/O Board is a very simple
> >>>>>>> design, it sits on the PC-104(ISA) bus, decodes its address and use the -IOW
> >>>>>>> line from the bus to strobe a latch. I can read and write to this board using
> >>>>>>> routines derived from DDK_IO like WRITE_PORT_UCHAR for example.
> >>>>>>>
> >>>>>>> I want to write a large block of data out on this I/O board at about 4MB/s.
> >>>>>>> I haven't been able to get this kind of perfomance in user mode.  Other than
> >>>>>>> reading the data from a hard disk and then writing it to the I/O board, the
> >>>>>>> CPU doesn't have to do much else.  Can I make some sort of TIMER ISR that
> >>>>>>> reads data from a buffer filled by an IST and writes it to the device.  The
> >>>>>>> IST reads the data from the DISK.
> >>>>>>>
> >>>>>>> I can modify the board design to have small FIFOs and/or interrupts.
> >>>>>>>
> >>>>>>> Is there a DRIVER example that would show me how to go about doing this?  Is
> >>>>>>> it possible to do a DMA transfer in this scenario?  There doesn't seem to be
> >>>>>>> a driver model that fits this kind of scenario.
> >>>>>>>
> >>>>>>>       I have read a great deal of information about writing drivers and am
> >>>>>>> familiar with most of the concepts.  I also have reviewed a few of the sample
> >>>>>>> source drivers.  I haven't actually created a driver myself.
> >>>>>>>
> >>>>>>>
> >>>>>>> Any suggestions would be greatly appreciated!!
> >>>>>>>
> >>>> .
> >>>>
> >> .
> >>
> .
> 
0
Utf
3/22/2010 2:38:01 PM
DMA data transfer does NOT go through any MMU translation, so what you 
program into the DMA address registers and the page register is the physical, 
not virtual, address of the buffer.  So, however you allocate it, it must be 
locked to physical memory, you have to be able to get the physical address of 
the buffer, and the buffer must NOT cross a 64k page boundary.  Based on all 
of that, I'd be inclined to predefine, as part of my memory layout, a 
reserved area, 64k in size, for the DMA buffer and not allocate or release it 
ever in the OS.

Paul T.

"knk53" wrote:

> Remi,
> 
>   Thanks again for responses.   My understanding of these concepts is 
> greatly improving.  
> 
>    I had a couple of questions about using the DMA method
> 
>    Our Board has an 8237 DMA Controller 
>    The DMA controller is at address 00H - 0FH  (Seems similar to your example)
>    The DMA Page Register is at 80H - 8FH
> 
>    I need to allocate a buffer to hold the data that I want to transfer.  Do 
> I use VirtualAlloc() and VirtualCopy() to create the buffer and map it to 
> physical memory?  Or can I use LocalAlloc() to get the buffer?  
> 
> The DMA controller needs a physical address, correct?
> 
> *******************
> 
>   You defined your page registers as follows:
> const DWORD	c_DmaPage[4] = {0x87,0x83,0x81,0x82};
> 
>   Is this a standard mapping?  Where do I find this information?   Is that 
> assigned in the registry somewhere??  The information for my processor board 
> only says that  the DMA Page Register is at 80H - 8FH.  Not which channel is 
> which??
> 
> 
> 
> 
> Thanks for all the help
> 
> Ken
> 
> 
> 
> "R. de Gravelaine" wrote:
> 
> > Hi Ken,
> > 
> > I am afraid there was not such 8237 driver sample before CE 6.0.
> > Anyway, the code in this driver is really bloated compared to your 
> > needs, so you'd probably better go on your own and write-down a few out 
> > instructions to start and stop a DMA transfer.
> > If not already done, read the 8237 (of equivalent) documentation and try 
> > to figure out how to use it, at both the hardware and software levels.
> > Also, remember that the "rep outsb" (or even better "rep outsw") test 
> > can show you what is feasible of not. If you are able to efficiently 
> > stuff your hardware through a "rep outs" instruction, you'll probably 
> > not need to switch to DMA. It is up to you.
> > 
> > AFAIK, there is no standard way to convey your platform parameters to 
> > this newsgroup, even if I think that Bruce Eitman (?) wrote something on 
> > his blog related to this topic (posting to CE newsgroup.)
> > 
> > Remi
> > 
> > 
> > Le 19/03/2010 19:19, knk53 a écrit :
> > > Remi,
> > >
> > >      Thanks for the info.  I am using CE 5.0.  It looks like the DMA8237
> > > driver is not in my directory tree.  I will review the sample code you posted
> > > and see if I can use that to test my board.  Is there a sample in CE 5.0??
> > >
> > >     For future reference, is there a standard way to convey the platform
> > > paramters when posting a question on these message boards?
> > >
> > > Thanks again
> > >
> > > Ken
> > >
> > > "R. de Gravelaine" wrote:
> > >
> > >> I suppose you are using CE 6.0 (yet another thing you did not tell.)
> > >> There is a 8237-based DMA driver available in
> > >> C:\WINCE600\PLATFORM\COMMON\SRC\SOC\X86_MS_V1\DMA8237.
> > >> If you feel that this driver is overkill for your problem, you can
> > >> certainly add an extra bunch of x86 instructions to setup a 8237
> > >> memory-to-IO transfer. Here is some code I used in the past to feed a
> > >> sound chip with PCM data (using an 8-bit DMA channel) :
> > >>
> > >> // 8-bits DMA registers (channels 0, 1, 2, 3)
> > >> #define DMA_ADDR	(PUCHAR)(g_DmaChan * 2)			// 0,2,4,6
> > >> #define DMA_COUNT	(PUCHAR)(g_DmaChan * 2 + 1)		// 1,3,5,7
> > >> #define DMA_MASK	(PUCHAR)0x0A
> > >> #define DMA_MODE	(PUCHAR)0x0B
> > >> #define DMA_FF		(PUCHAR)0x0C
> > >> #define DMA_PAGE	(PUCHAR)(c_DmaPage[g_DmaChan])	// 0x87,0x83,0x81,0x82
> > >>
> > >> const DWORD	c_DmaPage[4] = {0x87,0x83,0x81,0x82};	// DMA pages for
> > >> channels 0-3
> > >>
> > >>    - - - - - - - - - - - - - - - - - - - -
> > >> // Program the PC DMA for given transfer.
> > >> // The PC DMA is programmed to spin around the 2 output buffers.
> > >> // The audio chip DMA will be programmed to spin around only 1 buffer,
> > >> // interrupting the CPU after each chunk, but still fetching fresh data.
> > >> //
> > >> #define DMAMODE	0x58	// single, inc, autoinit, read
> > >> void StartPcDma()
> > >> {
> > >> 	// Start the PC DMA
> > >> #define	ADDRESS	AUDIO_DMA_BUFFER_BASE_PA
> > >> #define	COUNT	(AUDIO_DMA_PAGE_SIZE * 2)
> > >> 	__asm cli
> > >> 	OUTB(DMA_MASK, g_DmaChan | 4);			// disable DMA while programming
> > >> 	OUTB(DMA_FF, 0);						// clear the flip-flop
> > >> 	OUTB(DMA_MODE, g_DmaChan | DMAMODE);	// single, inc, autoinit, read
> > >> 	OUTB(DMA_COUNT, COUNT - 1);				// LO byte of count
> > >> 	OUTB(DMA_COUNT, (COUNT - 1)>>  8);		// HI byte of count
> > >> 	OUTB(DMA_PAGE, ADDRESS>>  16);			// physical page number
> > >> 	OUTB(DMA_ADDR, ADDRESS);				// LO byte address of buffer
> > >> 	OUTB(DMA_ADDR, ADDRESS>>  8);			// HI byte address of buffer
> > >> 	OUTB(DMA_MASK, g_DmaChan);				// done programming the DMA, enable it
> > >> 	__asm sti
> > >> #undef	COUNT
> > >> #undef	ADDRESS
> > >> } // StartPcDma
> > >>
> > >> Of course, you will need to change the DMAMODE value, to make sure that
> > >> your buffer physical address is below 16 MB (24 bits) and to adapt your
> > >> hardware for the DMA handshaking.
> > >>
> > >> HTH
> > >> Remi
> > >>
> > >>
> > >> Le 19/03/2010 13:34, knk53 a écrit :
> > >>> Remi,
> > >>>
> > >>>      Thanks for the response.  I will try using the outsb instruction as you
> > >>> indicated.  You mention that "Using DMA will be the most efficient solution".
> > >>>    Can you recommend a sample I could use to set up a test ?   I would like to
> > >>> try and have the DMA write data to this port and see if my pulse lengths get
> > >>> closer to what I expect.
> > >>>
> > >>> Ken
> > >>>
> > >>> "R. de Gravelaine" wrote:
> > >>>
> > >>>> Hi,
> > >>>>
> > >>>> The point here may be that your code has to be executed. This implies
> > >>>> memory reads and writes and this probably slows down the all process.
> > >>>> You did not tell us too much about your "stable Window CE x86 CEPC
> > >>>> platform" but depending on its chipset and the way it is tuned (caching,
> > >>>> etc.), executing your simple loop can take a lot of cycles.
> > >>>> You can try to see what happens when you use outsb instruction instead
> > >>>> of out:
> > >>>>
> > >>>>          __asm
> > >>>>         {
> > >>>> 	push si
> > >>>>            mov dx,WORD PTR addr
> > >>>>            mov si,offset buf	; 64KB buffer filled-up with 0,1
> > >>>> 	xor cx,cx	; 65536
> > >>>>            rep outsb
> > >>>> 	pop si
> > >>>>         }
> > >>>>
> > >>>> Of course, using DMA will be the most efficient solution, at least in
> > >>>> term of raw throughput.
> > >>>>
> > >>>> Taking this code into a driver (into the kernel) will not speed-up the
> > >>>> ISA bus accesses nor the code execution. However, it is generally a good
> > >>>> idea to put code that access the hardware into device drivers. Even if
> > >>>> CE 6.0 allows in and out instructions in user code, this will not
> > >>>> necessarily the case in future versions. And if your hardware becomes
> > >>>> memory-mapped instead of I/O-mapped (e.g. after switching to a PCI
> > >>>> architecture), you will have to write a driver to access it.
> > >>>>
> > >>>> HTH
> > >>>> Remi
> > >>>>
> > >>>>
> > >>>> Le 18/03/2010 22:14, knk53 a écrit :
> > >>>>> Paul,
> > >>>>>
> > >>>>>        Thanks for the reply.  Your initial analysis is correct.  The 8MHZ ISA
> > >>>>> Bus can only transfer about 2MB/s at 100% capactiy given only an 8bit
> > >>>>> transfer.  Please take a look at the following scenario and let me know if
> > >>>>> there are any other tests that may be worth doing.  Your help would be
> > >>>>> greatly appreciated.
> > >>>>>
> > >>>>>
> > >>>>>      The ISA Bus on my platform can be set to clock at 8Mhz or 16Mhz.  So if my
> > >>>>> application can survive with a 2MB/s throughput, the 16Mhz clock should be
> > >>>>> able to provide close to 4MB/s.  I would only be using 1/2 of the bus
> > >>>>> capability.  Or a 1/4 if I could switch to 16bit transfers.
> > >>>>>
> > >>>>>      I have a test running like the one below
> > >>>>>
> > >>>>>      unsigned char uc;
> > >>>>>      unsigned long x;
> > >>>>>      int addr;
> > >>>>>
> > >>>>>      addr = 0x79;
> > >>>>>      x=10000000;
> > >>>>>      uc=1;
> > >>>>>      while(x--)
> > >>>>>      {
> > >>>>>         __asm
> > >>>>>        {
> > >>>>>           mov dx, WORD PTR addr
> > >>>>>           mov al, uc
> > >>>>>           out dx, al
> > >>>>>        }
> > >>>>>        uc = uc ^ 1;
> > >>>>>      }
> > >>>>>
> > >>>>>      This test pulses my output wire 10000000 times.  It should take 5S at 8Mhz
> > >>>>> and 2.5S at 16Mhz.  The strange thing is, when I increased the clock speed
> > >>>>> from 8 Mhz to 16Mhz the pulse widths were not cut in half.   The results were
> > >>>>> at 8Mhz (Total Time: 9s, 800ns Pulse Width or 1.11MB/s) and at 16MHz (6.4S
> > >>>>> 600ns or 1.666 MB/s).
> > >>>>>
> > >>>>>      I was expecting the pulse widths as measured on an osciliscope to be
> > >>>>> closer to 250ns.   What is slowing the pulsing down?   Is it the code loop?
> > >>>>> Is the code being interrupted?   This is running as an application not in
> > >>>>> kernel mode.
> > >>>>>
> > >>>>>      Is it possible to set up a simple DMA transfer test for this???   DMA
> > >>>>> should transfer data hardware to hardware.  I should be able to see the 250ns
> > >>>>> pulses while the transfer is in progress.  Of course there would be some gap
> > >>>>> between the end of one transfer and the begining of the next.
> > >>>>>
> > >>>>>      Any thoughts would be appreciated.
> > >>>>>
> > >>>>> Ken
> > >>>>>
> > >>>>>
> > >>>>> "Paul G. Tobey [eMVP]" wrote:
> > >>>>>
> > >>>>>> I'd say that the driver scheme has almost nothing to do with the problem.
> > >>>>>> I'm not sure that you can get that throughput over your PC/104 bus, even if
> > >>>>>> you took all of the bus bandwidth.  Isn't the clock 8MHz on PC/104?  That
> > >>>>>> means that you'd have to transfer a *byte* every other clock to get 4MBPS.
> > >>>>>> I'd say that's crazy, even if you're writing a 16-bit, 2-byte, word on every
> > >>>>>> transfer, the maximum for PC/104.
> > >>>>>>
> > >>>>>> Paul T.
> > >>>>>>
> > >>>>>>> I am new to writing CE Drivers and don't know how to get started with the
> > >>>>>>> following problem.
> > >>>>>>>
> > >>>>>>> I have a stable Window CE x86 CEPC platform that I use for various projects.
> > >>>>>>> It is a headless system (no video, mouse, or keyboard).  It has a network
> > >>>>>>> port and 2 serial ports.
> > >>>>>>>
> > >>>>>>>     I would like to add a digital I/O board.  The I/O Board is a very simple
> > >>>>>>> design, it sits on the PC-104(ISA) bus, decodes its address and use the -IOW
> > >>>>>>> line from the bus to strobe a latch. I can read and write to this board using
> > >>>>>>> routines derived from DDK_IO like WRITE_PORT_UCHAR for example.
> > >>>>>>>
> > >>>>>>> I want to write a large block of data out on this I/O board at about 4MB/s.
> > >>>>>>> I haven't been able to get this kind of perfomance in user mode.  Other than
> > >>>>>>> reading the data from a hard disk and then writing it to the I/O board, the
> > >>>>>>> CPU doesn't have to do much else.  Can I make some sort of TIMER ISR that
> > >>>>>>> reads data from a buffer filled by an IST and writes it to the device.  The
> > >>>>>>> IST reads the data from the DISK.
> > >>>>>>>
> > >>>>>>> I can modify the board design to have small FIFOs and/or interrupts.
> > >>>>>>>
> > >>>>>>> Is there a DRIVER example that would show me how to go about doing this?  Is
> > >>>>>>> it possible to do a DMA transfer in this scenario?  There doesn't seem to be
> > >>>>>>> a driver model that fits this kind of scenario.
> > >>>>>>>
> > >>>>>>>       I have read a great deal of information about writing drivers and am
> > >>>>>>> familiar with most of the concepts.  I also have reviewed a few of the sample
> > >>>>>>> source drivers.  I haven't actually created a driver myself.
> > >>>>>>>
> > >>>>>>>
> > >>>>>>> Any suggestions would be greatly appreciated!!
> > >>>>>>>
> > >>>> .
> > >>>>
> > >> .
> > >>
> > .
> > 
0
Utf
3/22/2010 4:41:01 PM
 >     I need to allocate a buffer to hold the data that I want to 
transfer.  Do
 > I use VirtualAlloc() and VirtualCopy() to create the buffer and map it to
 > physical memory?  Or can I use LocalAlloc() to get the buffer?
 >
 > The DMA controller needs a physical address, correct?
 >

Right: the DMA controller does need a physical address, so LocalAlloc 
will not do it.
You can use VirtualAlloc/VirtualCopy, or MmMapIoSpace that does the same 
thing in a simplest way.
The point is that you only have 24 bits to define the buffer physical 
address, so it can't lay anywhere in your memory space (physical 
addresses past 16 MB are unusable.)
The best way to define this buffer is to reserve a memory range in low 
memory in config.bib's MEMORY section, such as:

    DMABUF 80110000  00010000  RESERVED

Here, a 64 KB buffer is reserved at physical address 0x110000 (1 MB + 64 
KB), which is supposed to be unused by CE on a CEPC (usually loaded at 
0x00200000 - see NK section.) You can actually place this buffer at 
almost any place in low memory where you know there is RAM, and that CE 
will not use.
Once you reserve your buffer, call MmMapIoSpace with its physical 
address (0x0000000000110000 in this example), its size (0x10000) and its 
caching flags (MmNonCached will be OK), and use the virtual address 
returned to pro programmatically access the buffer.

 >    You defined your page registers as follows:
 > const DWORD	c_DmaPage[4] = {0x87,0x83,0x81,0x82};
 >
 >    Is this a standard mapping?

Yes. Pure IBM PC legacy...

 > Where do I find this information?

First Google entry for "8237 page register" gave me 
http://zet.aluzina.org/index.php/8237_DMA_controller
This document seem to be very complete. You should really read it.

 > Is that assigned in the registry somewhere??

No. This is strict IBM PC/AT architecture.

Good Luck.
Remi
0
R
3/22/2010 5:11:27 PM
Remi,

   Thanks for all the help.   I think I am in good shape to get started with 
this project.   We need a little hardware modification to test the DMA but I 
think I understand the software aspect at this point.  

Thanks Again

Ken

"R. de Gravelaine" wrote:

>  >     I need to allocate a buffer to hold the data that I want to 
> transfer.  Do
>  > I use VirtualAlloc() and VirtualCopy() to create the buffer and map it to
>  > physical memory?  Or can I use LocalAlloc() to get the buffer?
>  >
>  > The DMA controller needs a physical address, correct?
>  >
> 
> Right: the DMA controller does need a physical address, so LocalAlloc 
> will not do it.
> You can use VirtualAlloc/VirtualCopy, or MmMapIoSpace that does the same 
> thing in a simplest way.
> The point is that you only have 24 bits to define the buffer physical 
> address, so it can't lay anywhere in your memory space (physical 
> addresses past 16 MB are unusable.)
> The best way to define this buffer is to reserve a memory range in low 
> memory in config.bib's MEMORY section, such as:
> 
>     DMABUF 80110000  00010000  RESERVED
> 
> Here, a 64 KB buffer is reserved at physical address 0x110000 (1 MB + 64 
> KB), which is supposed to be unused by CE on a CEPC (usually loaded at 
> 0x00200000 - see NK section.) You can actually place this buffer at 
> almost any place in low memory where you know there is RAM, and that CE 
> will not use.
> Once you reserve your buffer, call MmMapIoSpace with its physical 
> address (0x0000000000110000 in this example), its size (0x10000) and its 
> caching flags (MmNonCached will be OK), and use the virtual address 
> returned to pro programmatically access the buffer.
> 
>  >    You defined your page registers as follows:
>  > const DWORD	c_DmaPage[4] = {0x87,0x83,0x81,0x82};
>  >
>  >    Is this a standard mapping?
> 
> Yes. Pure IBM PC legacy...
> 
>  > Where do I find this information?
> 
> First Google entry for "8237 page register" gave me 
> http://zet.aluzina.org/index.php/8237_DMA_controller
> This document seem to be very complete. You should really read it.
> 
>  > Is that assigned in the registry somewhere??
> 
> No. This is strict IBM PC/AT architecture.
> 
> Good Luck.
> Remi
> .
> 
0
Utf
3/24/2010 12:41:01 PM
Reply:

Similar Artilces:

How do I create an xls for an OTR driver including trips and fees?
My husband is an over the road truck driver, I am in need of a spread sheet that can keep track of his mileage, load total, fees acrued, places of travel from pick-up to delivery with drop sites, etc. I am at a loss of how to achieve this as there are so many variables and was wondering if there are any templates for anything similar to our needs. That doesn't seem like many variables to me, and it seems that you just need all of those attributes as column headings, and then each row defines one trip. From your description I was not sure if one trip could include many plac...

Simple graph
I have a chart with zip codes and a population rate. ZIP RATE 80001 2.34 80002 1.23 80003 1.23 I want to make a chart that has the rate on the x axis and the number of times that rate occurs on the y axis. | | | * | | * |_________________________________ | | 1.23 2.34 Thank you. I will assume the ZIP and RATE stuff is in A1:B200 (labels in row 1) Label in G1 to read RATE (but leave it empty for now), label in H2 to read COUNT Make a list of rates in G2:G20 (say) In H2 =COUNTIF($B$2:$B$200,G2) Copy down the row Select H1:G20 and make a...

Drivers for percentage increase
I am trying to set up a driver to include in my budget profile so that my managers can select the percentage from a driver and see on each budget line what the outcome will be i.e staff costs may be calculated at 150,000 but if I used my driver to calculate an increase of 3.5% that would change the staff costs to 155,250. Can anyone help? Regards Jo I am not sure what you question is but this may help:- In cell A 2 I have 150,000 In cell B 2 I have 3.5% In cell C 2 I have:- =(A2*B2)+A2 - and this returns 155,250 to cell C 2. If my comments have helped please h...

Simple help with implementing Outlook-like GUI
Hi All. I am an experienced unix programmer who sometimes has to do something in the windows world, and always has newbie-questions. Basically I want to write an application program that looks like outlook in that it has nice icons down the left hand side that choose the content of the main area in the right hand side. So I started the MFC App wizard, and got me a SDI program with a CLeftFrame (CTreeView) and a CMainFrame (CFrameWnd). Then I prepared the following snippet of code to draw the buttons: // Create a pushbutton CBitmapButton* pmyButton; pmyButton = new CB...

Simple Simple Simple
Just started Excel (again) and need to make an easy speadsheet fo calculating square inches. Column A: Height Column B: Legnth Column C: Total Tags per 16 x 24 Column D: Cost per tag Figures I know: each sheet cost me $9.98. each sheet is 16 x 24 inches What I want to do is enter the Height, enter the Length and have th total (sum) be entered into columns C and D. I can't believe I forgot how to enter formulas. Any help will b appreciated. Thank you, Crai -- Message posted from http://www.ExcelForum.com Hi Craig, One Way, might be better ways but this'll work: List the colou...

Filter driver on boot device
I am writing a KMDF filter driver attached to the boot drive, so it loads with start_type = 0. I only want one read/write request in flight at a time. When I set the following in addDevice, I get a crash with "Inaccessible Boot Device:" WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE (&ioQueueConfig,WdfIoQueueDispatchSequential); ioQueueConfig.EvtIoRead = FilterEvtIoReadWrite; ioQueueConfig.EvtIoWrite = FilterEvtIoReadWrite; ioQueueConfig.EvtIoDeviceControl = FilterEvtIoDeviceControl; status = WdfIoQueueCreate(device, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, WD...

Simple hack to get $500 to your home. 06-05-10
Simple hack to get $500 to your home at http://uknews.tk Due to high security risks,i have hidden the cheque link in an image. in that website on left side below search box, click on image and enter your name and address where you want to receive your cheque.please dont tell to anyone. ...

Signature Capture pad / Display device
Does anyone know if the Signature Capture pads (I'm looking at the Hypercom Optimum L4100 ) will display a running receipt for the customer? Or would it be better to use a 2nd LCD screen to display that? Can't wait for your expert advice! Thanks guys! Well, the support for multi-function devices in RMS is improving, but it's not that good yet. It should be possible to create an add-in to do this, but you would have to take over all of the payment processing functions as well as rendering a receipt disply. It would be SOOO much easier to use your second option of an LCD...

Simple Query Wizard hangs
I am using Access 2003 When I initiate the "Simple Query Wizard", I am presented with the first screen - "What fields do you want in your query" When I click on the pulldown list to select a table, I get the following message: "The expression On Get Focus you entered as the event property setting produced the following error: the text you entered isn't an item in the list * the expression may not result in the name of a macro, the name of a user-defined function, or [Event Procedure]. * There may have been an error evaluating the function, event, or macro&q...

I Need a Simple Sales Software
Hello, I am looking for software to keep track of my prospects, customers, and the notes of the sales process. I spend about one hour a day on sales and marketing, so I prefer a simple and inexpensive software. Maximizer, Outlook, Act, and Goldmine seem made for the full-time professional salesperson. Please let me know if what I am looking for exists. Best Regards, T.I. ...

How do I get XP to skip installing a driver?
I have a Sprint cell phone and I only use the USB cable to charge it. It takes a long time to search for drivers that aren't there. After the long process of searching for drivers there is an option of not asking for the drivers anymore. Even though I have selected the option of not asking, I still get the search for drivers when I plug in the phone. How can I stop XP from asking for a driver? it is highly likely that this is a not a problem do to the operating system. what I would do is to search for an updated driver from sprint or contact them with the problem mo...

Make it more simple or intuitive to do simple things
I appreciate the fact that applications are becoming more versatile and able to do things that we hardly thought possible in the past but I feel that in this added complexity you are losing sight of the need to do simple things easily without resorting to trial and error or consulting "help" which often anyhow doesn't lead one straight to the solution! An example is how to produce a chart with a series of months i.e Jan Feb Mar etc appearing on the X axis. This is no doubt something that resulted naturally in the first versions of Excel charts or in a competitor's ea...

How to get device key (hardware key) path in kernel mode ?
Hi I want to get the hardware key path as the instance ID for my WMI event . Here is some WDM function IoOpenDeviceRegistryKey to open hardware key, but I can not get the hardware key path name in the tree of HKLM\SYSTEM\CurrentControlSet\Enum . Is there some way to get device key (hardware key) path in kernel mode ? Thank you . > Is there some way to get device key (hardware key) path in kernel mode = ? No ways. For instance IDs, create a device interface on your device and use its = string as an ID, this is the classic way. --=20 Maxim S. Shatskih Windows ...

Simple public folder permission problem
I have a public task list folder. However even though I have given everyone "Author" priviledges and full control of the directory, users cannot update the tasks (although they can create new ones). The changes to tasks get reset to their original values. Where should I look to fix this problem? Brian How did you grant Author Access, via Outlook or ESM? What do you meanyou gave them full control of the directory? "Brian Taylor" <taylorb@newsgroups.nospam> wrote in message news:e2hwumGrEHA.1160@tk2msftngp13.phx.gbl... > I have a public task list folder. Ho...

What is simple text?
When creating a custom list that includes a column of accounting formated data, I get an error message that 'fields without simple text will be ignored'. The result is all other data except the accounting formatted data. Help!!!! I suppose it means without the currency symbol and thousands delimiters. On Fri, 8 Apr 2005 11:01:04 -0700, TexMas <TexMas@discussions.microsoft.com> wrote: >When creating a custom list that includes a column of accounting formated >data, I get an error message that 'fields without simple text will be >ignored'. The result is ...

R4 ds/dsi firmware-drivers de R4 Sdhc. R4 ultra, R4 new, R4 III upgrade, R4 v3
Hola,, aqui teneis una web donde encontre una recopilacion de firmware o drivers de las R4 Sdhc ,R4 Ultra,R4 New, R4 III Upgrade. R4 Dsi, R4 ui. http://www.r4spain.com/tienda Pinchas en el enlace de arriba y en la parte inferior izda haces click en el boton DESCARGAR, aparecera un menu con muchos driver para distintas R4 DS. Espero que os sirva de ayuda. Saludetes Gorka ...

OPOS Driver
I have installed RMS to a new PC however now when I try to open the POS or Manager I get a message that says " OPOS driver not found" I went to the epson website but the download was not there. Anyone know what to do? Please help!!!! I had a similar problem and basically put a support request in to Epson. they emailed me the driver and... happy days. "Claudia Stevens" wrote: > I have installed RMS to a new PC however now when I try to open the POS or > Manager I get a message that says " OPOS driver not found" I went to the > epson website but t...

simple question
Okay, I have a very simple question. Where do the old posts go after they run off the last page of this newsgroup? Sometimes I would like to refer to a post that I remember seeing in October, but is no longer on the current section. The search function seems to only search current posts as well. If anyone has some input please email me at joep@siboneylg.com Thanks kindly. have you tried google groups, they keep archived old posts: http://groups.google.co.uk/groups?q=microsoft.public.greatplains&hl=en "Joe Proehl" <joep@siboneylg.com> wrote in message news:099701c5...

Simple Macro is not so simple
Hi all, I am trying to record a macro which will automatically perform the insert > comment function to a selected cell. Should be easy right? Alas no Danny There's sample code on my web site, for inserting comments: http://www.contextures.com/xlcomments03.html Aardvark wrote: > Hi all, > > I am trying to record a macro which will automatically perform the insert > > comment function to a selected cell. Should be easy right? Alas no -- Debra Dalgleish Excel FAQ, Tips & Book List http://www.contextures.com/tiptech.html Wow! Nice one :-) Thank you M...

(Error 1004) Object Defined Error ...simple code
I have the following simple simple code: Dim s as String s = WeekdayName(1) ' Causes Error 1004 Why would the above call to "WeekdayName(1)" suddenly cause an Object Defined Error?? My program has been working nicely for awhile, but now all of a sudden it halts at the above line??? What the heck is going on??? Robert Crandal Hi Robert, It works fine for me. However, checking out Help, the first day of week parameter is supposed to default to Sunday (or 1) as the first day of the week but it appears to default to zero. Tested in xl2002 and x...

clipping region of a device context.
can someone explaing me what's a clipping region in a device context? if i draw for example different circles in a window client area when i resize the window these objects disappear because the whole client area is invalidated by windows, so what represents the clipping region?The whole client area? And what about if(pDC->RectVisible(pElement->GetBoundRect()))//obtain enclosing shape rect pElement->Draw(pDC); // ...draw it this function checks if the enclosing rect of a shape, for example a circle, overlay the clipping region...what it exactly means? Maybe th enclosing rect...

vb--simple simple
hi, anyone know how to copy a combobox selection to a specific cell b using vb code in a command box -- Message posted from http://www.ExcelForum.com i cant see this in the userform. i know you can do this with a normal combo box which is not in a for but lost when in a userform -- Message posted from http://www.ExcelForum.com What's a "command box"? Can you give an clear example of what you want to do? -- Jim Rech Excel MVP "stevieh >" <<stevieh.16v8yw@excelforum-nospam.com> wrote in message news:stevieh.16v8yw@excelforum-nospam.com... | hi, | |...

Is device resource depletion *cumulative* ??
'Never heard of resource depletion for add-on devices until it happened to my own PC. This concerns PCI expansion slots specifically. There's a chunk of memory allocated to each add-on device, and an IRQ assignment, yes? My PC has 3 PCI slots and I've been juggling a variety of add-ons in them for years. Occasionally I have switched a device to a different slot for reasons, and devices have come and gone. Finally I must've gone too far! I removed a TV/FM card, forgetting to explicitly direct Windows XP to Uninstall it first. Then I moved a modem card from anoth...

Formula question -simple for those who know
Hello I'm trying to add a number that was calculated by means of a formula in one column to the sum of a different column. Example: Column A (running balance) Column B (sum) =+e5+c6-d6 =sum(h1:h8) Col A's number is running balance. I copied the formula down so that the next row changes the formula to =+e6=c7-d7 I want that running balance to add to a sum in another column. I can add the first cell to it, but it doesn't change if the running balance changes. I know that is because it's pointing to that single...

Pretty simple question
Hello I use Excel 97 in work. I have a frustrating problem. If I have two Excel workbooks open then, in order to switch between them, I have to go to the menu bar and select <Window> and then the appropriate workbook. I am used to Excel 2000 where I can just click the workboook 'icons / tabs' along the bottom of my screen. This is far better. How can I change Excel 97 to allow the open workbooks to display as icons/tabs along the bottom of the screen (as is standard these days). Please help lower my blood pressure... Regards Alex Alex, I don't think that was an ...