strange mmap_device_memory error

We have a FPGA board which we try to communicate with.
See enclosed FPGA_WriteTest.c and FPGA_ReadTest.c.
The FPGA is memory mapped at 0xFFF00.

Using a logic analysator we see that the write test writes as it should -
The SMEMW signal goes active with FFF00 on the adress bus.
But the read test does not read, there’s no SMEMR with adresses
above 0x0FFFF on the adress bus.

Any ideas?

QNX6.1, Digital Logic PC/104 Pentium III CPU.

Cheers / Tom

Tomas H?gstr?m <tomas@scandicraft.se> wrote:

This is a multi-part message in MIME format.
--------------A4D3CDBEBCBC22D66EE72D78
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

We have a FPGA board which we try to communicate with.
See enclosed FPGA_WriteTest.c and FPGA_ReadTest.c.
The FPGA is memory mapped at 0xFFF00.

Using a logic analysator we see that the write test writes as it should -
The SMEMW signal goes active with FFF00 on the adress bus.
But the read test does not read, there’s no SMEMR with adresses
above 0x0FFFF on the adress bus.

Any ideas?

When you did a mmap_device_memory() do you put PROT_NO_CACHE in
the flags?

QNX6.1, Digital Logic PC/104 Pentium III CPU.

Cheers / Tom

--------------A4D3CDBEBCBC22D66EE72D78
Content-Type: application/x-unknown-content-type-C_auto_file;
name=“FPGA_ReadTest.c”
Content-Transfer-Encoding: base64
Content-Disposition: inline;
filename=“FPGA_ReadTest.c”
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmlu

Also, posting as inline text, rather than as an attachement, makes this
readable and editable.


QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Sorry, thought it would turn up inline.
Yes, NOCACHE is enabled, but it almost seems
that it’s caching anyway when reading.

Tom


8<-----------------------------------------------------------------------
FPGA read test:
8<-----------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/neutrino.h>


#define STATIC_REG_OFF 0x7E
#define MIN_DELAY 200000

static volatile uint16_t* Static_reg;
static volatile uint16_t value ;

int main (int argc, char* argv[] )
{
int delay = 500000;
int verbose = 1;
uint8_t* BaseAddr;

w_value = 0xdcba ;
switch (argc)
{
case 3:
verbose = strtol( argv[2], NULL, 0 );
/* fall through to next case */

case 2:
if (strcmp( “help”, argv[1] ) == 0)
{
printf( “Usage: %s [delay in micro sec (min %d if verbose)] [Be verbose (1/0)]\n”, argv[0], MIN_DELAY );
return EXIT_FAILURE;
}

delay = strtol( argv[1], NULL, 0 );
if (verbose != 0 && delay < MIN_DELAY) // Don’t kill the console!
delay = MIN_DELAY;
/* fall through to next case */

case 1:
break;

default:
printf( “Usage: %s [delay in micro sec (min %d if verbose)] [Be verbose (1/0)]\n”, argv[0], MIN_DELAY );
return EXIT_FAILURE;
}

if (ThreadCtl(_NTO_TCTL_IO, 0) == -1)
{
perror( “Error when setting thread IO privilege, must be root to run this code” );
exit( EXIT_FAILURE );
}

BaseAddr = (uint8_t*)mmap_device_memory( NULL, 0x0100, PROT_READ | PROT_WRITE | PROT_NOCACHE, 0, 0x0fff00 );
if ( BaseAddr == MAP_FAILED )
{
perror( “Mapping device memory area to process failed” );
exit( EXIT_FAILURE );
}

Static_reg = (volatile uint16_t*) (BaseAddr + STATIC_REG_OFF);

printf( “\nMapped static register to %lx\n”, Static_reg );

printf( “Read test starting (Hit Ctrl+C to exit)…\n\n” );
sleep(1);

while(1)
{
value = *Static_reg;

if (verbose != 0)
printf( “Register value: %X\n”, value );

usleep(delay);
}

return 0;
}



8<-----------------------------------------------------------------------
FPGA write test:
8<-----------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/neutrino.h>


#define STATIC_REG_OFF 0x7E
#define MIN_DELAY 200000

int main ( int argc, char* argv[] )
{
uint8_t* BaseAddr;
uint16_t* Static_reg;
uint16_t value = 0xABCD;
int delay = 500000;
int verbose = 1;

switch (argc)
{
case 4:
verbose = strtol( argv[3], NULL, 0 );
/* fall through to next case */

case 3:
delay = strtol( argv[2], NULL, 0 );
if (verbose != 0 && delay < MIN_DELAY) // Don’t kill the console!
delay = MIN_DELAY;
/* fall through to next case */

case 2:
if (strcmp( “help”, argv[1] ) == 0)
{
printf( “Usage: %s [value] [delay in micro sec (min %d if verbose)] [Be verbose (1/0)]\n”, argv[0], MIN_DELAY );
return EXIT_FAILURE;
}

value = strtol( argv[1], NULL, 0 );
break;

case 1:
break;

default:
printf( “Usage: %s [value] [delay in micro sec (min %d if verbose)] [Be verbose (1/0)]\n”, argv[0], MIN_DELAY );
return EXIT_FAILURE;
}

if (ThreadCtl(_NTO_TCTL_IO, 0) == -1)
{
perror( “Error when setting thread IO privilege, must be root to run this code” );
exit( EXIT_FAILURE );
}

BaseAddr = (uint8_t*)mmap_device_memory( NULL, 0x0100, PROT_READ | PROT_WRITE | PROT_NOCACHE, 0, 0x0fff00 );
if ( BaseAddr == MAP_FAILED )
{
perror( “Mapping device memory area to process failed” );
exit( EXIT_FAILURE );
}

Static_reg = (uint16_t*) (BaseAddr + STATIC_REG_OFF);

printf( “\nMapped static register to %lx\n”, Static_reg );

printf( “Write test starting (Hit Ctrl+C to exit)…\n\n” );
sleep(1);

while(1)
{
if (verbose != 0)
printf( “Writing value: %X\n”, value );

*Static_reg = value;
usleep(delay);
}

return 0;
}

Tomas H?gstr?m <tomas@scandicraft.se> wrote:

Sorry, thought it would turn up inline.

No problem. Sometimes the world is tricky that way.

Yes, NOCACHE is enabled, but it almost seems
that it’s caching anyway when reading.

At first pass, that’s what it sounds like to me as well.

You may have already tried this… you said that a write would
cause you to see the lines changing, but not a read. Did you do
the read after the write? What happens if you just do the read test?

Hm…this looks like x86.

Not sure what might be going on. This looks like it might be getting
lower level in the behaviour of the CPU and cache stuff than I know.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Yes, it’s strange. We have tested with an old 166MHz Pentium
machine now, and we get the same results. Absolutely no
read accesses to the region we’re mapped in the FPGA board to.
Write access work fine. A read after write doesn’t work either.

Cheers / Tom

Tomas H?gstr?m <tomas@scandicraft.se> wrote:

Yes, it’s strange. We have tested with an old 166MHz Pentium
machine now, and we get the same results. Absolutely no
read accesses to the region we’re mapped in the FPGA board to.
Write access work fine. A read after write doesn’t work either.

Can you put your QNX box into text mode and try reading VGA
memory at 0xb8000?

Here’s a little sample program that does it:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>

int main()
{
void ptr;
char buff[80
25*2];
int i;

// ptr = mmap( NULL, 4*1024, PROT_READ|PROT_WRITE|PROT_NOCACHE,
// MAP_PHYS|MAP_SHARED, NOFD, 0xb8000 );

ptr = mmap_device_memory( 0, 4*1024, PROT_READ|PROT_WRITE|PROT_NOCACHE,
0, 0xb8000 );

printf(“ptr is %d\n”, ptr);

memcpy(buff, ptr, 80252);
for( i = 0; i< 80252; i+=2 )
{
if (!(i%80)) printf("\n");
printf("%c", buff );
}
}

Cheers / Tom


QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Hi,

We changed the address of the FPGA board to a lower one
and now it seems to work! I.e. we had some kind of
hardware conflict.

Cheers / Tom

Tomas H?gstr?m <tomas@scandicraft.se> wrote:

Hi,

We changed the address of the FPGA board to a lower one
and now it seems to work! I.e. we had some kind of
hardware conflict.

When all else fails, check the hardware. :slight_smile:

Thanks for letting me know.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.