This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

External memory with F2833x

Other Parts Discussed in Thread: CONTROLSUITE, TMS320F28335

I have run this chip out of memory with a font array for an LCD and need a way to expand it. I'm sure there's a way to do it (perhaps using the external interface?) but I've never had to do it.

What kind of memory is appropriate for expanding the code memory bank? How do I tell Code Composer "This needs to go to the external memory, not internal"? How does the processor know how to run the code from external memory or fetch instructions from there?

  • The XINTF interface on the TMS320F2833x can be used for this purpose.  You can connect external Flash and/or SRAM to the device.

    There is an example in the device support for TMS320F2833x in controlSUITE called xintf_run_from that illustrates connecting SRAM and executing from SRAM.  The same principle could be used with NOR flash.

  • I need a bit more of a "high-level" explanation of how this works please... I think I understand that there are 32 data lines, 20 address lines, 3 different chip select lines (for the different zones), and a handful of other status and control lines. What I don't understand is how the program knows to install "this" section of code to external memory and not "that" section. When the program gets to "this" section, does it automatically go to the XINTF module looking for that code?

    What part of the example program "xintf_run_from" points CCS to external memory?

    Is there a way to dynamically point code to external memory as the program size increases, like an overflow, or is the programmer responsible for keeping track of memory used?

  • Keith Wheaton said:

    I need a bit more of a "high-level" explanation of how this works please... I think I understand that there are 32 data lines, 20 address lines, 3 different chip select lines (for the different zones), and a handful of other status and control lines. What I don't understand is how the program knows to install "this" section of code to external memory and not "that" section. When the program gets to "this" section, does it automatically go to the XINTF module looking for that code?

    This is part of the process in the code generation tools that is described to the linker.  Through the use of the linker command file, a description of the TMS320F28335 memory map is provided as well as providing insight into which sections are to be allocated to which memory segments.  The linker command file must describe the available resources in accordance with what is physically on the device/board as indicated by the device datasheet (ie. Figure 3-2 of the TMS320F28335 datasheet) and your board if you connect external memory on the XINTF bus.

    There is a very comprehensive training/workshop that provides illustrations of this concept.  You can look at the Student Guide to get a quick walk through of the linker and linker command file, specifically in the Programming Development Environment section.

    http://processors.wiki.ti.com/index.php/C2000_Piccolo_Multi-Day_Workshop

     

    Keith Wheaton said:

    What part of the example program "xintf_run_from" points CCS to external memory?

    Looking at the linker command file for the xintf_run_from example, the section that is copied from internal memory (in this particular case RAM) to external memory is defined by the named section "xintffuncs".  You can see in the SECTIONS declaration, this particular code section is "loaded" into internal memory and then "run" from external memory.  There will be code executed as a part of the program to explicitly copy from this "loaded" memory to the "run" memory.

    You will see a call made to MemCopy() that uses the labels defined by the linker in the linker command file to use as the start address of the load area and end address of the load area.

     

    Keith Wheaton said:

    Is there a way to dynamically point code to external memory as the program size increases, like an overflow, or is the programmer responsible for keeping track of memory used?

    A description of the capability of the linker is provided in the C28x Assembly Language Tools User's Guide.  However, there is the ability to allocate a section to a list of potential memory segments.  The linker will look for a memory segment that has enough space to place the entire section in it.  If it can not find a memory segment large enough, it can then switch to the next memory segment indicated.  It will not spread a segment across memory segments.

     
  • After about a day of digesting, I think I have a better understanding but still have a few questions.
    1) After looking at a few of the memory devices available on the marketplace, is it safe to say that the minimum pins that have to be used are the XD, XA,  XWE0,  XRD, and XZCSx? This is all assuming an asynchronous device with 16-bit words and 20 address bits (enough to use the full address range of zone 6 or 7).

    2) When data is read by the processor from external memory, is the data clocked in on the rising edge of the XRD pin?

    3) For timing purposes, does a 150MHz CPU frequency = 150MHz SYSCLKOUT frequency or is there a divider from the base oscillator frequency and the system clock frequency?

    From the "xintf_run_from" example program:

    4) I found the variables XintffuncsLoadStart, XintffuncsLoadEnd, and XintffuncsRunStart that seem to define the boundaries, so to speak; I see where these are declared in DSP2833x_GlobalPrototypes.h and are referenced in line 130-132 of the linker file as well. What I don't see is where these variables are being given a value (I would expect something that matches the address range of the XINF zone 7). Can you point out where these variables are getting their values?

    5) What what is the purpose of the apparent function calls in the linker file LOAD_START(), LOAD_END(), and RUN_START()?

  • Keith Wheaton said:

    After about a day of digesting, I think I have a better understanding but still have a few questions.
    1) After looking at a few of the memory devices available on the marketplace, is it safe to say that the minimum pins that have to be used are the XD, XA,  XWE0,  XRD, and XZCSx? This is all assuming an asynchronous device with 16-bit words and 20 address bits (enough to use the full address range of zone 6 or 7).

    Yes, that is correct.  The necessary signals are address (XA), data (XD), write enable (XWE0), read enable (XRD) and a chip select (XZCSx).  The TMS320F28335 supports both 16-bit and 32-bit memories (ie. width of XD).

     

    Keith Wheaton said:

    2) When data is read by the processor from external memory, is the data clocked in on the rising edge of the XRD pin?

    Correct.  The timing diagram for the read access by the TMS320F28335 is found in the datasheet, specifically in section 6.14.

     

    Keith Wheaton said:

    3) For timing purposes, does a 150MHz CPU frequency = 150MHz SYSCLKOUT frequency or is there a divider from the base oscillator frequency and the system clock frequency?

    Yes, CPU frequency = SYSCLKOUT frequency.  There are downstream dividers that are configurable.

     

    Keith Wheaton said:

    From the "xintf_run_from" example program:

    4) I found the variables XintffuncsLoadStart, XintffuncsLoadEnd, and XintffuncsRunStart that seem to define the boundaries, so to speak; I see where these are declared in DSP2833x_GlobalPrototypes.h and are referenced in line 130-132 of the linker file as well. What I don't see is where these variables are being given a value (I would expect something that matches the address range of the XINF zone 7). Can you point out where these variables are getting their values?

    These labels are assigned an address by the linker itself.  The linker command file is defining these symbols and assigning values.  The C source code then references these labels via the extern classification.

     

    Keith Wheaton said:

    5) What what is the purpose of the apparent function calls in the linker file LOAD_START(), LOAD_END(), and RUN_START()?

    These are defined in the C28x Assembly Language Tools User's Guide in Section 7.5.9.7.  These are operators for the linker command file to define the load time start address, load time end address and run time start address of the particular section.

  • Thank you so much for your patience. I think it is finally starting to sink in but let me make sure I have a proper understanding. The linker file has the Page 0: definition of

    RAML1      : origin = 0x009000, length = 0x001000

    which sets aside 0x001000 address spaces starting at 0x009000 for whatever the program wishes to place there. Additionally, the XINTF zone 7 is allocated with the statement:

    ZONE7A     : origin = 0x200000, length = 0x00FC00

    where only 0x00FC00 addresses are provided as opposed to the full 0x0FFFFF. Later, in SECTIONS, the label of 'xintffuncs" says "This information should be loaded at the location of 'RAML1' and executed from 'ZONE7A'. For the purposes of external use, define _XintffuncsloadStart as the address where loading should start, _XintffuncsLoadEnd as the address where loading should stop, and _XintffuncsRunStart as the address where the code should be copied to and run from."

    In the file "Example_2833xCodeRunFromXintf.c" the statements

    #pragma CODE_SECTION(cpu_timer0_isr,"xintffuncs");
    #pragma CODE_SECTION(cpu_timer1_isr,"xintffuncs");

    tells the linker that the programmer wishes the functions "cpu_timer0_isr" and "cup_timer1_isr" to be handled according to the declaration of "xintfuncs" in the linker file. The rest of the program is written as would be normally and handled by the linker.

    Is my understanding on this matter (finally) correct?

  • Keith Wheaton said:

    Is my understanding on this matter (finally) correct?

    You got it!

  • Great!

    Since I will have a couple rather large arrays used as bit-mapped fonts, I would want to declare them as

    const char Font_Array [x_size] [y_size] = {{.....},{...

    and map .econst to the XINTF?