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.

Problem bringing up DSP

Other Parts Discussed in Thread: OMAP-L138, SYSCONFIG, SYSBIOS, OMAPL138

We have a custom OMAP-L138 system where a bare metal ARM brings up a SYS/BIOS DSP, and it works, but now I am trying to bring up SYS/BIOS 6.3.33 on the ARM.

I am having trouble controlling power for the DSP from the ARM under SYS/BIOS.   I cannot use the PSP, since evidentally it is not built for the ARM (and other posts around here indicate it is not buildable for the ARM), so I am trying to use the same "bare metal" code for bringing up the DSP that I know works in the "bare metal" environment, but I am seeing some significant problems.

More concretely, if I follow the same "wake the DSP code" that works well for the bare metal system, I get the following error when I try to connect to the DSP after I "wake" it,

C674X_0: Error connecting to the target: (Error -1144 @ 0x0) Device core is hung. The debugger attempted to recover debug control, but was unsuccessful. Power-cycle the board. If error persists, confirm configuration and/or try more reliable JTAG settings (e.g. lower TCLK). (Emulation package 5.0.569.0

Lowering TCKL on the emulator settings has no effect.

My DSP start routine is simply,

uint32_T ST4_dsp_Start(void *dsp_start_vector)
{
  CSL_PscRegsOvly PSC0 = (CSL_PscRegsOvly)CSL_PSC_0_REGS;
  CSL_SyscfgRegsOvly SYSCONFIG = (CSL_SyscfgRegsOvly) CSL_SYSCFG_0_REGS;

  ST4_sysconfig_Unlock();
 
  /* force the timer0 clock source to be DSP, since I can't figure out how to do that with .cfg */
  SYSCONFIG->SUSPSRC |= CSL_SYSCFG_SUSPSRC_TIMER64P_0SRC_MASK;

  // Unlock the system config registers.
  CLRBIT(PSC0->MDCTL[CSL_PSC_DSP], CSL_PSC_MDSTAT_LRST_MASK);
       
  // Write the reset vector
  SYSCONFIG->HOST1CFG = (uint32_T)dsp_start_vector;
       
  // Power up the DSP
  ST4_lpscTransition(PSC0, 1, CSL_PSC_DSP, CSL_PSC_MDCTL_NEXT_ENABLE);
       
  // Release the DSP from reset
  SETBIT(PSC0->MDCTL[CSL_PSC_DSP], CSL_PSC_MDSTAT_LRST_MASK);
       
  ST4_sysconfig_Lock();

  return (ERR_NO_ERROR);

}

void ST4_lpscTransition(CSL_PscRegsOvly psc, uint32_T in_domain,
                        uint8_T in_module, uint8_T in_next_state)
{
  uint32_T domain_bit;
  if (in_domain == 0)
    domain_bit = (CSL_PSC_PTCMD_GO0_SET << CSL_PSC_PTCMD_GO0_SHIFT);
  else
    domain_bit = (CSL_PSC_PTCMD_GO1_SET << CSL_PSC_PTCMD_GO1_SHIFT);

  // spin until existing transitions are done.
  while (CHKBIT(psc->PTSTAT, domain_bit)) {}

  // if we are already in the requested state...just return.
  if(CHKBIT(psc->MDSTAT[in_module], CSL_PSC_MDSTAT_STATE_MASK) == in_next_state)
    {
      return;
    }

  // setup the transition...clear the bits before setting the next state.
  CLRBIT(psc->MDCTL[in_module],
         (CSL_PSC_MDCTL_NEXT_SWRSTDISABLE | CSL_PSC_MDCTL_NEXT_SYNCRST | CSL_PSC_MDCTL_NEXT_DISABLE));
  SETBIT(psc->MDCTL[in_module], in_next_state);

  // kick off the transition.
  SETBIT(psc->PTCMD, domain_bit);

  // spin until transition is done.
  while (CHKBIT(psc->PTSTAT, domain_bit)) {}

  while (CHKBIT(psc->MDSTAT[in_module], CSL_PSC_MDSTAT_STATE_MASK) != in_next_state) {}
}

(The bit with the SUSPSRC was an attempt to fix the problem, since it appeared that timer 0 was being claimed by the ARM while in my bare metal system it seems to be assigned to the DSP.   I get the same result with or without it, but thought I should leave it in, since it was different than my bare metal.   I also reassign the ARM Clock to be timer 2, so rudely putting it back under DSP control shouldn't be a big deal).   SETBIT and CLRBIT are obvious routines that work for the bare metal, and ST4_lpscTransition implements the process described in the PSC documentation (again, that works for the bare metal).

To simplify debugging, I also have disabled the MMU on the ARM.  Again: same results with MMU enabled and disabled, but I am leaving it this way.

So, any clue as to how to proceed?   Am I barking up the wrong tree with booting the DSP this way in the first place (even though it works for the bare metal)?   Is there a whole different approach I should take?

  • For OMAP-L138 if SysBIOS runs on both the ARM and DSP side, the IPC package can be used to manage the ARM/ DSP communication. IPC includes the API to properly initialize the DSP out of reset to a known good state and run SysBIOS. A pre-built example for IPC is included and can be created quickly in CCS5. Once created, you can examine the source code to see how it is done and further customize it for your system.

    To try this out with CCS, you need to create 2 projects, one for ARM and one for DSP. The project is a template under "IPC and I/O Examples" and then "OMAPL138 Examples". Select for example the "OMAPL138: Notify (ARM)" for the ARM side and "OMAPL138: Notify (DSP)" for the DSP side.

    Other code examples on how to bring DSP out of reset from ARM can be found in the OMAP-L138 Starterware package available at http://www.ti.com/tool/starterware-dsparm and UG at http://processors.wiki.ti.com/index.php/StarterWare_01.10.01.01_User_Guide   

  • Thanks for the reply.

    I believe my "bare metal" code started life at one point as a version of the OMAP-L138 starter kit.  I'm downloading the most recent one to make sure, but the code derived from that version works at bringing up the DSP so I can load my SYS/BIOS system on to it. 

    I installed the two OMAPL138 examples.  I see how to use them if I load both via JTAG and run them.

    I don't see any indication of how the SYS/BIOS ARM example program puts the DSP in reset, powers up the DSP, sets the start vector, and takes the DSP out of reset to start it running at that start vector.   I see no indication of the API you mentioned in IPC, and when I grep the IPC code for "PSC" or "SYSCFG" (the registers that would be required to do that process, as far as I know), I see nothing.   When I try to do that process after booting SYS/BIOS on the ARM using my bare metal code (derived from the startup kit, I believe, and which works with the ARM not running SYS/BIOS), then I get that weird connection error when I try to connect to the DSP.

    Am I just not seeing the DSP boot up API?  Is this kind of DSP manipulation expected to happen in a GEL file/Boot ROM loader?    Is it not expected to happen from the ARM itself under SYS/BIOS?   If this is so, are there any examples, both for the GEL and the AISgen configuration tool?

    Thanks,

        Jay

  • Just for more information:  I built and loaded the ARM and DSP Notify examples for OMAP-L138.

    As I expected, they did not work as is.  I needed to bring in a GEL file to initialize DDR to load the ARM Notify.   When the ARM notify ran, it did nothing to set up the DSP, so I ran a GEL function which is supposed to wake the DSP, and when I connect to the DSP, I the same kind of "Device core hung" message I was getting before.  If I muck around with my bare metal code and get the ARM and DSP set up properly, and then reload the examples on both cores, I can get it to work.

    So, obviously I am missing a step or two here in your explanation.   It does not appear that the examples contain everything I need for the ARM to bring up the DSP running from the correct vector location.

    It does appear that the StarterWare package is significantly different than what I inherited to start my bare metal code, but not having an EVM board, I can't really test it.   I am working with an existing, custom OMAP-L138 board.   In addition, it doesn't seem to show how to boot the DSP from the ARM running SYS/BIOS, and I already have a working example of booting the DSP from the ARM while not running SYS/BIOS.

    One difference I note is that my bare-metal ARM code runs in supervisor mode (through calling _call_swi(0x50000)).   As I would expect, trying to jump my initialization routine into supervisor mode using this trick causes SYS/BIOS to have an exception, as I suspect it totally hoses the task scheduling.   Is it possible that I can't do what I want reliably in System mode?

    I can't be the only person who wants to boot SYS/BIOS on both cores of an OMAP L138.   Am I even asking the right questions?  Is there some entirely different paradigm for booting I should be using?   

       Jay

     

  • More information:

    I tried poking in a "Branch to self" instruction (0x0000A120) at the DSP start vector to make sure the system was running "known" state, but that still didn't seem to help.

    What I see is after the SYS/BIOS ARM code takes the DSP out of reset (according to PSC00ARM->MDLCTRL15 going to 0x00000103), I try and connect to the DSP core with CCS5, there is a pause and I see

     C674X_0: Error connecting to the target: (Error -1143 @ 0x0) Device core was hung. The debugger has forced the device to a ready state and recovered debug control, but your application's state is now corrupt. You should have limited access to memory and registers, but you may need to reset the device to debug further. (Emulation package 5.0.569.0)

    I hit OK, and the DSP is suspended at 0xc0000000, but I tring to load a program results in

    C674X_0: Trouble Reading Memory Block at 0xc0000000 on Page 0 of Length 0x4: (Error -2172 @ 0xB0) Unable to communicate with the emulator. Confirm emulator configuration and connections, reset the emulator, and retry the operation. (Emulation package 5.0.569.0)
    C674X_0: File Loader: Data verification failed at address 0xC0000000 Please verify target memory and memory map.
    C674X_0: GEL: File: C:\Workdir\Vision\Software\ST4\DSP\apps\st\Debug\ST4_DSP_app.out: a data verification error occurred, file load failed.

    That first error message was right on the button:  I don't have access to memory on the DSP (although I still do on the ARM). 

    So, I am betting that I am missing something so obvious that it doesn't occur to anyone to explain it to me.    I guess that I need the person who created the OMAPL138 Notify example to tell me, or point me to the explanation of, EXACTLY how to run that example, especially point me to the GEL files that they use.   Is there some kind of GEL file required to connect to the DSP as well as the ARM?   If so, why, since I didn't need that with my "bare metal" ARM code setting up the DSP?

    When I look at the SYSCFG register, the only difference I can see between the "working" bare metal code and the not-working SYS/BIOS code is that SUSPSRC is 0xFFFFFFFF for the working code and is 0xD7FFFFFF, i.e., I am using timer 2 for the clock on the ARM, and I can't get timer 0 to be set for the ARM no matter what I do in the .cfg.   I don't see how that could possibly make a difference, and I don't know how to change it (I tried using Timer.timerSettings[0].ownerCoreId =1 , but that had no effect).   Are there other registers I should be looking at that could explain the different behavior?

  • There could be various reasons. If the DSP memory is not accessible from ARM, it could be that the DSP is not enabled (power, clock). On OMAP-L138 after booting, the ARM puts the DSP in reset. The UBL then initializes the DSP reset address and starts the DSP using PSC. If the DSP address is not initialized to valid code, the DSP could be performing bad code preventing the emulator from halting the DSP core. The steps to start the DSP is outlined in the section "DSP Wake Up" in the TRM.

    You may want to check the PLL0 STATUS register (SYSTAT) to see if PLL0 CLK1 is enabled (bit 0). If the DSP is on (which it should), check the DSP reset vector to make sure it points to valid code.

  • Loc,

    Thanks for pointing me at the PLL0 registers.  It turns out that the SYSTAT->CLK1 is enabled, but that, unbeknownst to me, the PLL multipliers and divisors were all off by one from what I needed.  Tthe values I got from the inputs to the "config_pll0" and "config_pll1" routines in my bare metal code all had one subtracted to them before going into the PLL registers, while the "device_PLL0" and "device_PLL1" routines in my GEL file did not, despite the input parameters being named exactly the same thing, so when I just copied the values from the bare metal PLL setup to the GEL file setup, they all ended up off by one.

    It turned out with those bizarre settings I happened to be able to connect to and run the ARM, but the DSP connection was exceedingly unpredictable.   When I got the PLL0 and PLL1 settings rational, I was able to connect to the DSP and load SYS/BIOS code there as well.

    I'm glad I didn't have to go down the UBL path, since I haven't had a bootloader beyond the ROM bootloader for this system so far.

    That seems to fix it for me, thanks again,

         Jay