This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Accessing External Memory Devices

Hey all,

I am using uVision 3 and a Phytec 2294 board.

I have an external memory device connected to the phytec expansion board. The external device is using /CS0, although from talking to phytec, I am not sure if that is quite right.

I have set up the external memory space in the project options like so:
Start: 0x80000000 Size: 0x4

When I define a variable like :

#define volatile var x __at 0x8000000

and step through my code, any write/read to that variable doesnt seem to take place at the right addresses.

Can anyone give a clue as to what I may have missed?
Thanks

Doug

Parents Reply Children
  • Dan,

    Thanks for the quick reply.

    I have also used :

    #define var          (*((volatile unsigned char *) 0x83000000))

    Those are the only two ways I can think of to declare the variable.

    Is there a syntax that I am missing?

  • Now that syntax (casting an integer constant to a pointer, then dereferencing) is what I have seen (and used).

    A couple of things, but I am not familiar with your particular ARM:

    • Is any memory controller and/or EBI set up to handle that address?
    • Can that address handle byte-only access or is it (32-bit) word-only?

  • Dan,

    Thanks again for the response.

    Its actually an 8 bit wide bus that I am trying to talk to. I think thats why we picked /CSO since it defaults to 8bit.

    I guess I am unsure how to set up the EMC to handle that address. Any help would be appreciated :)


    Thanks again

  • Well, I'm a little out of my element here since I'm not familiar with your device. I have used the Atmel AT91RM9200 which has the memory controller decoding the four highest bits such that 0x10000000-1FFFFFFF asserts /CS0 and 0x80000000-8FFFFFFF asserts /CS7, then one sets up the EBI to configure which memory controller /CS0 is assigned to (in my case a static memory or burst flash controller), then one sets up the assigned memory controller for the read/write/access/width/timing parameters. So how does your ARM do it? ;-)

    I would break the problem in two. First, have the compiler generate assembly output and make sure that your syntax can generate the proper instructions to access memory at any arbitrary address. Then make sure that your system is configured for the proper address asserting /CS0.

    Do you have access to a scope and can probe /CS0?

    Does Phytec document the external interface?

    Does that board's BIOS or BSP already configure the memory controller(s)?

    Does Phytec provide examples of using this interface?

    I don't know if I'll muster up the motivation to dig into it myself. If I do, it will be out of curiousity to see what boards Phytec offers, which ARMs they use, their documentation quality, etc. for possible client use.

  • Dan,

    Here is the basic paramaters I know about:

    There are 4 memory bank select registers

    Bank 0 - 4

    Bank 0 addresses 80000000 ( CS0 )
    Bank 1 addresses 81000000 ( CS1 )
    Bank 2 addresses 82000000 ( CS2 )
    Bank 3 addresses 83000000 ( CS3 )

    Each of those banks can be configured and going through the phytec documentaion, it says that bank 0 is used for boot mode, whatever that means.

    I have set up bank 3 to be 8 bit wide , set wait states, etc.

    In the target options, I have specifed external memory space 0x83000000 with a size of 4 bytes for now, since I only need a few addresses to get going.

    It is to my understanding that when I access a variable defined at a particualr address, it will assert the appropriate chip select signal( I confirmed this with Phytec Tech Support )


    I ran my code in debug mode and checked the memory map however, it doesnt appear that the area of memory I am selecting is getting mapped.

    Im cleary missing a piece of informaiton somewhere, rather it big or small

    thanks

    Doug

  • "I have set up bank 3 to be 8 bit wide , set wait states, etc."

    So you have code to write the configuration value into BCFG3, or does the IDE generate code to do this for you?

    "In the target options, I have specifed external memory space 0x83000000 with a size of 4 bytes for now, since I only need a few addresses to get going."

    But have you defined any variable to be there? That is, a variable with a defining declaration to allocate storage space there? Using the macro like we've discussed should generate code to read/write to that location, but it does not allocate storage space (which is not necessarily a problem, but it won't show up in a memory map).

    "It is to my understanding that when I access a variable defined at a particualr address, it will assert the appropriate chip select signal"

    Yes, regardless of whether you have a normal storage-allocating defining declaration and linker controls to locate it at that particular address, or use a macro, the chip select would be your indication that you are accessing your memory space.

    Is your board jumpered correctly to route the chip select where you want it?

  • The IDE has a "wizard" type interface that lets me set up the banks.


    I have defined a variable at the location 0x83000000

    I have verified that the CS0 signal from the micro is routed correctly to the external device.

    Thanks

    Doug

  • "The IDE has a "wizard" type interface that lets me set up the banks."

    How does the wizard get the configured value into the BCFG3 register?

    "I have defined a variable at the location 0x83000000

    I have verified that the CS0 signal from the micro is routed correctly to the external device.


    This is an area of (my) confusion -- isn't 0x83000000 /CS3?

  • Ooops...

    I have been mistyping my addresses in the forum lol I have defined an address at 0x80000000 not 0x83000000. Sorry about that.

    I am assuming that the wizard "magically" puts it there somehow, I have verified that the bank register has the correct values as well.

    Doug

  • Then skimming chapters 4 and 5 of your hardware manual, I'm guessing that the ARM is either booting out of internal flash and CS0 is available for your use, or that at some point after booting from a CS0-selected memory device, CS0 is then later remapped to 0x80000000 for your use, right?

    If this dual mapping is an area of possible confusion or contention, can you use one of the other of CS1-3?

  • Then skimming chapters 4 and 5 of your hardware manual, I'm guessing that the ARM is either booting out of internal flash and CS0 is available for your use, or that at some point after booting from a CS0-selected memory device, CS0 is then later remapped to 0x80000000 for your use, right?

    when the cpu starts, it begins execution at address 0x00000000., but I think I could tell it to REMAP anywhere I wanted to in theory. It may just be easier to use a different CS. What do you think. Primarily I wanted to know if my methodolgies to address this outside memory were correct.

    Because when I looked in the disassembly, when I wrote to my address, it was still writing in the 0x00000000 space.

    Thanks

    Doug

  • Let's put aside any issues related to linker-located data objects and simply access memory locations directly. Take the incomplete snippet below and look at its disassembly. You should see code generated to read from those addresses. If so, then you should be able to incorporate it into a test on the actual hardware, while playing around with the BCFGn registers and probing the CSn signals on the board with a scope to look for activity.

    #define ADDR_TO_P(addr) ((volatile unsigned char *)(addr))
    
    void foo(void)
    {
        unsigned char b;
    
        for (;;)
        {
            b = *ADDR_TO_P(0x80000000);
            b = *ADDR_TO_P(0x81000000);
            b = *ADDR_TO_P(0x82000000);
            b = *ADDR_TO_P(0x83000000);
        }
    }

  • Dan,

    Thanks again.

    When I plug that code in to my program, I get the following:

    *** error 65: access violation at 0x80000000 : no 'read' permission

    *** error 65: access violation at 0x80000001 : no 'read' permission

    *** error 65: access violation at 0x80000002 : no 'read' permission

    *** error 65: access violation at 0x80000003 : no 'read' permission

    Is there somewhere I need ot set up access permissions?

  • Well, the good new is that you are no longer accessing 0x00000000. But where is this message coming from -- IDE, simulator, some kind of target OS?

    http://www.keil.com/support/docs/814.htm

    Simulator/debugger perhaps...

  • That last one was my fault, I didnt have those address in my memory map.

    After adding the ranges for those addresses, it went through the code just fine.

    However, when I checked the address of b, it still came back with somethign in the 0x0000000 range. Am i misunderstanding this representation?

    I guess my problem is to find out how to create those adddress mappings automatically, so its that way everytime i download to the chip.