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.

C6701 Booting without external RAM

Other Parts Discussed in Thread: TMS320C6701

Hi,

Due to operating conditions in our system, our CPU card is only being populated with the TMS320C6701 and some external EEPROMs.
I am using CCS 3.1 to compile the code. I am using hex6x from CCS 3.3 (hex6x from CCS 3.1 was buggy) to generate the secondary bootloader and bin files.
On a protoype card that has SDRAM, I was able to generate a bin file that successfully booted the card with the code running from SDRAM.

In the cdb file, I changed the sections that were placed in SDRAM to be in IPRAM...seemed like a simple task.
When I program EEPROM and try to boot, I have some success. The DSP initializes the EMIF correctly, it also runs the copy table and then jumps to
c_int0...so far so good. But the opcodes at the c_int0 starting address are not correct, the opcode should be "00000212", a B.S2 instruction I think but
the opcode is something else and the opcodes following the start address are just random STW instructions. I looked at the bin file using a binary reader and
it contains junk opcodes. So it looks like hex6x generated garbage code.

Anybody run in to this before?

Also, I will need to generate a version of the code that allows the jtag emulator to connect and run code with the code running from IPRAM. Once the code is
running, I can use the UART download feature that I wrote to download the application to EEPROM.

The emulator and the hex6x tools seem to work fine when there is external RAM available but not without.

Thank you in advance for your assistance,
Bill.

  • Have you inspected the generated bin file for the external memory?  You see proper opcodes there?  I would not have guessed the issue is with the hex conversion tool.  I would assume it to be something like an overlap between your secondary bootloader and your application.  Are you sure that one is not trampling on the other?

  • Hi Brad,

    I've been working with Tim Harron in the past and we have made some head way. He suggested I post to this forum for more help. Thanks for responding.

    So I looked at a working secondary bootloader so that I could understand the copy table format....spra999 is not completely clear on this data point. I'm good now. I followed the copy table for the image that does not work. The copy table looks fine and if the bootloader executes properly, then the correct opcode will show up in the c_int0 location. awesome!!! But when the DSP executes the code, the overwrite to IPRAM does not occur. I stuffed 55 pattern in IPRAM and then re-ran the bootloader. Still no writes to IPRAM and then A4 register is pointing at IPRAM space.

    Is there some flag or register bit that does not allow the DSP to over-write its IPRAM space while it is running from IPRAM?

  • May be a better way to go is to move the copy_table to eeprom. Then the DSP is moving data from eeprom to ipram. thoughts?

  • Never mind about moving the copy_table to eeprom. I checked and the problem is that the dsp cannot over-write ipram.

  • This could be related to cache.  Exactly what address(es) are you writing the code (e.g. I do not see the term IPRAM in the datasheet)?  Are you using the CPU to copy the code?

  • Hi Brad,

    I looked through my really old notes and found the following statement:

    1. Note that the secondary boot loader (boot_c671x.s62) cannot copy sections from FLASH to IPRAM due to hardware limits in the C6701. Therefore, when building the file to program to flash, do not place any sections in IPRAM. Suggest putting all code sections in SDRAM.

    I would have written this statement when I was working with Bernard Thompson at TI some 3-4 years ago.

    IPRAM refers to the internal program memory of the C6701 DSP. I think SPRU186 defines the internal program memory as residng at 0x1400000.

    May be you're right about the cache...not sure.

    Not sure if this possible but what if we were to massage the bin file to put all the code sections in their proper place rather than rely on the bootloader. Some utility program that reads the copy_table, finds the IPRAM specific sections and rewrites a new bin file. Then we could rely on the DSP's internal DMA mechanism that brings in 64K bytes of data from eeprom on chip select CE1 to IPRAM before allowing the DSP to come out of reset.

    So how soon can I expect a variant of hex6x that can do this for me? hehe

  • Ah, yes, I got it now.  That memory is straight program memory.  It is not physically connected to the data bus of the CPU.  The only way to get code into that memory is to use the DMA to put it there.  So you'd have to put some special logic in your bootloader to use the DMA to load that memory.

  • Dang.

    Okay, I give. I see that I can't re-order the code sections in the copy_table.  We could do something funky with the binary if the hex6x utility had some more switches like "-no-code" to omit adding code sections to the copy_table and if it also had "-code_start" so we could set the starting address of the code to be above the copy_table...that would be too good to be true.

    I guess the DMA solution is my only alternative. Do you have some sample assembler code for the DMA controller on the C6701 DSP that would resolve this issue? 

  • Sorry, I don't have any example code.  I think you would just need to modify your secondary bootloader to look at the address of the copy being performed and if the address falls into that program memory then you would need to do a DMA transfer.

  • Hi Brad,

    I'm looking at the DMA controller approach and I'm also experimenting with the hex6x utility.

    Tim Harron proposed an idea before where I could split the code and data sections into 2 seperate files. I'm running with this idea where the initialized data is in one file with an associated bootloader and copy_table. The other file contains just the code sections, (.text, .sysinit & .bios). The idea is really close now except the data binary file needed the hwi_vec code to appease the -boot option but I think I also need this section in the code binary file. This approach, if it works, will place the data section and bootloader in the 1st 0x2000 locations of the eeprom and the code sections from 0x2000 through 0xFFFF locations of the eeprom.

    Have you seen this tried before? Is it doable or am I going to run in to some other pitfall?

  • Posting for Brad as he's traveling:

    Be careful with the hiw_vecs section. If you use the HWI_dispatchPlug API the CPU will try to write into the vector table which will not be possible in IPRAM.

    I've never tried this before but it should be do-able.
  • Dang.

    I re-arranged the bin files and got the DSP to boot using just IPRAM and IDRAM. But interrupts don't work. I do select the HWI Dispatcher in the cdb file, otherwise the overhead for the ISRs is huge. I tried to put the hwi_vec table in IDRAM and and now the DSP no longer boots. I'll need to debug this a little to see if its finger problems.

    If your last statement is correct, then I need some external SDRAM for the hwi_vect table, it can't reside in internal memory. Is that your conclusion as well? 

  • willshad said:
    If your last statement is correct, then I need some external SDRAM for the hwi_vect table, it can't reside in internal memory. Is that your conclusion as well? 

    This is the easiest way to plug a vector into the table. They definitely need to be placed in the IPRAM and not the IDRAM. I think that if you write a vector table in code (as opposed to using the plug function dynamically) that you should be able to keep the table in internal memory; however, I do not see a good/easy way to update the table dynamically at run-time.

  • The c6000 CPU is inherently a Harvard architecture way down close to the core.  In newer devices the memory map is unified at the L2 level, though 6701 doesn't have any L2!  The CPU can execute instructions from the L1P, though it can not do data accesses to L1P.  Similarly, for the L1D the CPU can do data accesses but it cannot execute instructions from L1D.

    Are you trying to actually reconfigure interrupts for different purposes at run-time?  Why not set these up ONCE in your tcf file and then you don't ever have to mess with them again?

    The only way to get code into the L1P is using DMA.  So if you want to modify your vector table you need to use the DMA to do it.  For example, create a little "scratchpad" where you use the CPU to configure a vector the way you want it to look and then use the DMA to copy it to L1P.

    Another way you could do it would be to configure BIOS such that the vector table is in external memory.  You could use that entire vector table as your scratchpad and then DMA the entire thing into internal memory (just need to do a one-time reconfig of the ISTP register). In this case you could still use APIs like HWI_dispatchPlug though you would have to follow it up with a DMA copy of the BIOS vector table to your L1P vector table.

    Brad

  • Brad,

    You & Tim are talking way over my head now.

    I'm not very familiar with the HWI_Dispatcher. I just know that if I don't use it (select the HWI_Displatcher in the cdb file), then my ISRs have too many push/pops and take forever. The h/w guys are starting to push me towards eliminating interrupts and use polling...egads.

    I am not trying to reconfigure interrupts for different purposes at run-time. I sent Tim a zip of my project. The file named tcdpisr.c has all the ISRs defined. I understand the L1D and L1P stuff just fine. I have no problems with setting up the interrupts just ONCE, just tell me how because I thought that was what I was doing.

    BTW: I'm using CCS 3.1 to compile so I have a cdb file. But I use CCS 3.3 to emulate because it works much better than 3.1, CCS 3.3 converts my cdb file to a tcf file for emulation.

    Bill.

  • As long as you're putting the interrupt names into the cdb/tcf file rather than calling HWI_dispatchPlug() at run-time then you shouldn't have an issue.  I just got confirmation from the BIOS team that the interrupt table is populated with statically declared HWI objects at build time.

    FYI, you can change the version of the compiler you're using in CCS 3.3 such that you're producing the same output as 3.1.  Then you could do everything in 1 IDE.

    Brad

  • Starting out as a good week.

    Got the darn thing to run from IPRAM. Used 1 command file to generate a bootable image that just initializes variables in the IDRAM. Used a second command file to place the code just above the secondary bootloader. Then, combined the binary data from the two hex6x output files into 1binary file that has the bootloader placed from address 0 to 0x2FFF and the code (text, bios, hwi_vec, sysinit) placed from 0x3000 to 0xECE0. This allows the DSP's internal bootloader to copy my entire image into IPRAM. I also had to set the Program Memory Cache control to "memory-mapped" so as to disable the cache.

    Thank you & Tim for all your assistance.

    Any ideas about how to generate the final binary file without manually editing the individual binary files? I know we could probably throw some utility together to do it but was wondering if hex6x or some variant of it can do the trick. 

    Bill.

  • Bill,

     I do not know of a good way to do this without copy/pasting or writing a little script to do it automatically. Maybe someone else who does know how can chime in.

  • The better option is to combine everything into one project such that you only have one file to deal with.  Tell me more about how you're doing the bootloading and maybe I can help you.

    Brad

  • I think Tim is correct. We've started to write a utility to do the merge.

    But here are the command files that I'm using. The map files show that the bootloader section stops before address 0x3000. The code starts at address 0x3000 and goes to 0xece0. In the code map file, you can also see a gap between the BIOS and hwi_vec section. Our utility will put zeroes in the bin file to make up this gap. Kind of hokey butits working.

    ti-discussion.ZIP