Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

GNUARM weirdness ?

2005-07-19 by DECwiz (Fred van Kempen)

Hi All,
 
I've stumbled into something very weird this weekend, and I can't seem
to figure out what the problem is.  Here is a snippet of code:
 
/* Write a value to a CS8900A I/O register. */
static void
lan_iow(unsigned char *base, int reg, unsigned short val)
{
    unsigned char *p;
    unsigned char x;
 
    /* Write low and high byte of register number. */
    p = (base + reg);
printf(" IOW(%d, %d) P=%08lx\n", reg, val, p);
    x = (val & 0xff);
    *p = x;
    p++;
    x = ((val >> 8) & 0xff);
    *p = x;
printf(" done\n");
}

/* Read data from a CS8900A I/O register. */
static unsigned short
lan_ior(unsigned char *base, int reg)
{
    unsigned char *p;
    unsigned char x;
    unsigned short val;
 
    p = (base + reg);
printf(" IOR(%d) P=%08lx\n", reg, p);
    x = *p;
printf(" IOR(%d) P=%08lx L=%02x\n", reg, p, x);
    val = x;
    x = *(p + 1);
    val |= (x << 8);
printf(" IOR(%d) XXX P=%08lx VAL=%04x\n", reg, p, val);
    return(val);
}

/* Write a value to one of the CS8900A PacketPage registers. */
static void
lan_ppw(unsigned char *base, int reg, unsigned short val)
{
    /* Write low and high byte of register number. */
    lan_iow(base, CSIO_PPTR, (unsigned short)reg);
 
    /* Write low and high byte of value. */
    lan_iow(base, CSIO_PDATA0, val);
}

/* Read data from one of the CS8900A PacketPage registers. */
static unsigned short
lan_ppr(unsigned char *base, int reg)
{
printf("PPR(%d)\n", reg);
    /* Write low and high byte of register number. */
    lan_iow(base, CSIO_PPTR, (unsigned short)reg);
printf(" IOW done\n");
 
    /* Read the low and high bytes of the value. */
    return(lan_ior(base, CSIO_PDATA0));
}
 
This is basically a set of routines to write data from and to the I/O mode
registers of the CS8900A ethernet chip, which is connected to the CPU
over the EMC interface, in 8-bit mode.  The EMC bank is configured as
follows:
 
    /*
     * Put the CS8900A bank in 8-bit mode.
     *
     * IDCY = 1+1 ~ 33ns
     * WST1 = 8+3 (read)  ~183ns
     * WST2 = 6+1 (write) ~ 117ns
     * RBLE = 1 (enable byte lane mode)
     * WP = 0, BM = 0
     */
    BCFG2_bit.MW = 0;
    BCFG2_bit.IDCY = 1;
    BCFG2_bit.WST1 = 8;
    BCFG2_bit.WST2 = 6;
    BCFG2_bit.RBLE = 1;
    BCFG2_bit.WP = 0;
    BCFG2_bit.BM = 0;
 
    /* Enable the A0 line for this (CS2) bank (P3.0 / A0). */
    PINSEL2 |= 0x00804000;
 
which I believe is correct.
 
The above code works fine when compiled with the IAR compiler (which
I normally use, by the way).  However, when trying to make this package
suitable for a friend's use (who uses the GNUARM environment) I found
that things are NOT working.
 
Basically, the driver *hangs*.  It hangs at the lines doing:
 
printf(" IOR(%d) P=%08lx\n", reg, p);
    x = *p;

right after printing the IOR(12) P=8200000C
 
line.  Meaning, it's hanging in the "x = *p" line (whatever is generated by
GCC for that).  Assembler output is useless; the function has been
optimized out (even with -O0.)
 
I checked the schematics, and since there is no IORDY line, the ARM
basically never knows when a memory READ is finished, so it would not
WAIT for it, either....
 
Does anyone know what could cause this ?
 
I *do* have DABORT etc traps installed, and they don't fire.  They do if I
specify "bad" memory addresses above, and the above code also works
OK if I use "real" (RAM) memory.  So its just the dealing with the memory-
mapped range at CS2 that gets messed up....
 
Heeeeelp!
 
--fred
 

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

[Non-text portions of this message have been removed]

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.