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.

28027F - serial_flash_programmer hangs on F021_SendPacket

Expert 1570 points
Other Parts Discussed in Thread: CONTROLSUITE, MOTORWARE

Hi,

I'm trying to use the serial_programmer. I'm using Controlsuit version v3.4.0 - June 27, 2016.

files for 28027 - V230.

I'm able to download the kernel, but after that the programmer hangs.

Looking at the implementation of the PC side, (C:\ti\controlSUITE\device_support\~Utilities\serial_flash_programmer), I see major differences compared to the 28027 side:

1. 28027 waits for:

if (SCIA_GetOnlyWordData() != 0x08AA) return FLASH_ENTRY_POINT;
ReadReservedFn();

which the PC-side does not support.

2. 28027 does not send back ACK.

and so on...

Is this solution verified to work?

Further, something I noticed in the cmd file of the kernel:

BOOTROM    : origin = 0x3FF27C, length = 0x000D44

According to SPRUFN6A, the bootrom are in 0x3FF4B0.

Thanks a lot

  • What command line arguments are you using for the serial flash programmer?

    Please see www.ti.com/lit/sprabv4

    sal
  • Please specify as a command line argument "-d f2802x"

    The serial flash programmer should not be calling the f021 functions of the serial flash programmer. For f2802x, the serial flash programmer will call the f05 functions.

    sal
  • Hi Sal,

    That solved it...Works like a charm! Thanks a lot.

    I'm wondering what makes the key (0x08AA) appear in the first data of the .txt files? is it the build when specifying -sci8 ?

    I already managed to take out the kernel load and autobaud functions from the bootloader. Works great.

    Next I will try to integrate the kernel in my application. I guess that I will need to load all the kernel functions to RAM, and that's it? I will give it a try.

    Some few other questions please:

    1. Do I need to CodeStartBranch.S ? if so, why is it needed ?

    2. What about the .cmd BOOTROM address definition ? 

    BOOTROM    : origin = 0x3FF27C, length = 0x000D44

    According to SPRUFN6A, the bootrom are in 0x3FF4B0.

    Do we need to change it?

    Thanks a lot for your great support!

  • Yes. Put the kernel in RAM and it should work.

    If you are running from standalone, you application will need code start branch to set up the C environment and branch to the start of your application.

    The boot rom section in the linker command file shouldn't effect your application at all. I am not sure why it is in the cmd file. You do not need to change it.

    Please verify this post of my previous post to close the thread. If you have any more questions, you can either post to this thread or open another.

    Thanks!

    sal

  • Hi Sal,

    I got the bootloader working. I'm calling the kernel from my application.

    What I'm wondering is what to do with the EntryAddr that the bootloader returns?

    What I did is:

    - from main, call the bootloader:

    uint32_t    EntryAddr;

    EntryAddr = StartBootLoader();

    where StartBootLoader is the start of the kernel:

    DisableDog();

    .

    .

    Now what should I do with the EntryAddr that is returned?

    Should the calling function (from where I'm running the above line, in this case the main) run from RAM?

    I tried doing

    return (StartBootLoader());

    but I get compiler error message:

    error #119: a void function may not return a value

    Thanks a lot

  • The calling function should run from RAM since the kernel programs flash. When programming flash, you need to run from RAM.

    The EntryAddr is the start of the program that is being programmed. You can see this from the Hex format. There should be documentation on the Hex format in the Technical Reference Manual or Boot ROM section of the documentation.

    You can branch to the EntryAddr or branch wherever your application needs too.

    sal
  • Hi Sal,
    How do I branch to a pointer stored in a C variable ?
    Can you post a small code snippet ?

    Thanks a lot
  • By the way, if I call the kernel from within a running application, do I still need the "Exit_Boot.asm" file ? What is the purpose of it ?
  • Exit_Boot will return from the kernel and branch to the entry point of the application you just downloaded and programmed.

    www.ti.com/.../spru513j.pdf

    sal
  • Hi Sal,

    I've decided to issue an ESTOP after the bootloader finishes, and let the user reset the device.

    So I'm excluding the Exit_Boot.asm from the build.

    I'm experiencing strange behavior with the output .txt file.

    The PC side was hanging all the time. I've placed several ESTOP instruction inside CopyData(), and I found that the kernel returns an error here:

    status = Flash_Program((Uint16 *) BlockHeader.DestAddr, (Uint16 *)progBuf, BlockHeader.BlockSize, &FlashStatus);
              if(status != STATUS_SUCCESS)
              {
                    asm("    ESTOP0");

                  return;
              }

    The error code of Status is 12 - STATUS_FAIL_ADDR_INVALID

    I'm checking BlockHeader variable and I see the address is 0x50... Which is in RAM...It is the stack location... Very strange.. The block size is 512 (decimal).

    I'm attaching the .cmd, .map, .txt files. (I've changed the extension of .cmd and .map

    2604.F28027F_wt_FlashAPI.cmd.txt
    /*
    // TI File $Revision: /main/7 $
    // Checkin $Date: July 6, 2009   17:25:36 $
    //###########################################################################
    //
    // FILE:  F28027.cmd
    //
    // TITLE: Linker Command File For F28027 Device
    //
    //###########################################################################
    // $TI Release: 2802x C/C++ Header Files and Peripheral Examples V1.29 $
    // $Release Date: January 11, 2011 $
    //###########################################################################
    */
    
    /* ======================================================
    // For Code Composer Studio V2.2 and later
    // ---------------------------------------
    // In addition to this memory linker command file,
    // add the header linker command file directly to the project.
    // The header linker command file is required to link the
    // peripheral structures to the proper locations within
    // the memory map.
    //
    // The header linker files are found in <base>\DSP2802_Headers\cmd
    //
    // For BIOS applications add:      DSP2802x_Headers_BIOS.cmd
    // For nonBIOS applications add:   DSP2802x_Headers_nonBIOS.cmd
    ========================================================= */
    
    /* ======================================================
    // For Code Composer Studio prior to V2.2
    // --------------------------------------
    // 1) Use one of the following -l statements to include the
    // header linker command file in the project. The header linker
    // file is required to link the peripheral structures to the proper
    // locations within the memory map                                    */
    
    /* Uncomment this line to include file only for non-BIOS applications */
    /* -l DSP2802x_Headers_nonBIOS.cmd */
    
    /* Uncomment this line to include file only for BIOS applications */
    /* -l DSP2802x_Headers_BIOS.cmd */
    
    /* 2) In your project add the path to <base>\DSP2802x_headers\cmd to the
       library search path under project->build options, linker tab,
       library search path (-i).
    /*========================================================= */
    
    /* Define the memory block start/length for the F28027
       PAGE 0 will be used to organize program sections
       PAGE 1 will be used to organize data sections
    
       Notes:
             Memory blocks on F2802x are uniform (ie same
             physical memory) in both PAGE 0 and PAGE 1.
             That is the same memory region should not be
             defined for both PAGE 0 and PAGE 1.
             Doing so will result in corruption of program
             and/or data.
    
             The L0 memory block is mirrored - that is
             it can be accessed in high memory or low memory.
             For simplicity only one instance is used in this
             linker file.
    
             Contiguous SARAM memory blocks or flash sectors can be
             be combined if required to create a larger memory block.
    */
    
    MEMORY
    {
    PAGE 0:    /* Program Memory */
               /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */
    
       OTP         : origin = 0x3D7800, length = 0x000400     /* on-chip OTP */
       CSM_RSVD    : origin = 0x3F7F80, length = 0x000076     /* Part of FLASHA.  Program with all 0x0000 when CSM is in use. */
       BEGIN       : origin = 0x3F7FF6, length = 0x000002     /* Part of FLASHA.  Used for "boot to Flash" bootloader mode. */
       CSM_PWL_P0  : origin = 0x3F7FF8, length = 0x000008     /* Part of FLASHA.  CSM password locations in FLASHA */
    
       IQTABLES    : origin = 0x3FE000, length = 0x000B50     /* IQ Math Tables in Boot ROM */
       IQTABLES2   : origin = 0x3FEB50, length = 0x00008C     /* IQ Math Tables in Boot ROM */
       IQTABLES3   : origin = 0x3FEBDC, length = 0x0000AA     /* IQ Math Tables in Boot ROM */
    
       //ROM         : origin = 0x3FF27C, length = 0x000D44     /* Boot ROM */
       RESET       : origin = 0x3FFFC0, length = 0x000002     /* part of boot ROM  */
       VECTORS     : origin = 0x3FFFC2, length = 0x00003E     /* part of boot ROM  */
       FLASHC_D    : origin = 0x3F0000, length = 0x003FFF     /* on-chip FLASH B, C and D */
       P_RAML0     : origin = 0x008000, length = 0x000900     /* on-chip PRAM block L0 */
    //	FLASHA    : origin = 0x3F6000, length = 0x001F80     /* on-chip FLASH A */
    	BOOTROM    : origin = 0x3FF4B0, length = 0x422
    
    PAGE 1 :   /* Data Memory */
               /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation */
               /* Registers remain on PAGE1                                                  */
    
       RAMM0_M1    : origin = 0x0000250, length = 0x0003B0     /* on-chip RAM block M0 + M1. 0x600 to 0x800 reserved for InstaSPIN */
       STACK_M0	   : origin = 0x000050, length = 0x000200
       D_RAML0     : origin = 0x008900, length = 0x000700     /* on-chip DRAM block L0 */
       D_FLASHB	   : origin = 0x3F4000, length = 0x001FFF
       D_FLASHA    : origin = 0x3F6000, length = 0x001F7F     /* on-chip FLASH A */
    }
    
    /* Allocate sections to memory blocks.
       Note:
             codestart user defined section in DSP28_CodeStartBranch.asm used to redirect code
                       execution when booting to flash
             ramfuncs  user defined section to store functions that will be copied from Flash into RAM
    */
    
    SECTIONS
    {
       /* Allocate program areas: */
       .cinit              : > FLASHC_D     PAGE = 0
       .pinit              : > FLASHC_D,    PAGE = 0
       .text               : > FLASHC_D     PAGE = 0
       codestart           : > BEGIN        PAGE = 0
       ramfuncs            : LOAD = FLASHC_D,
                             RUN = P_RAML0,
                             LOAD_START(_RamfuncsLoadStart),
                             LOAD_END(_RamfuncsLoadEnd),
                             RUN_START(_RamfuncsRunStart),
                             PAGE = 0
    
       csmpasswds          : > CSM_PWL_P0   PAGE = 0
       csm_rsvd            : > CSM_RSVD     PAGE = 0
    //	.InitBoot          : > P_RAML0,    PAGE = 0
    
       /* Allocate uninitalized data sections: */
       .stack              : > STACK_M0     PAGE = 1 FILL = 0xABCD
       .ebss               : > D_RAML0      PAGE = 1
       //ebss_extension      : > P_RAML0      PAGE = 0
    //   .esysmem            : > RAMM0_M1     PAGE = 1
    
       rom_accessed_data   : > RAMM0_M1     PAGE = 1
    
       /* Initalized sections go in Flash */
       /* For SDFlash to program these, they must be allocated to page 0 */
    /*
       .econst     : LOAD = D_FLASHB,
                     RUN = D_RAML0,
                     LOAD_START(_econst_start),
                     LOAD_END(_econst_end),
                     RUN_START(_econst_ram_load),
                     PAGE = 1
    
       .switch     : LOAD = D_FLASHB,
                     RUN = D_RAML0,
                     LOAD_START(_switch_start),
                     LOAD_END(_switch_end),
                     RUN_START(_switch_ram_load),
                     PAGE = 1
    */
    
    .econst             : > FLASHC_D       PAGE = 0
       .switch             : > FLASHC_D       PAGE = 0
    
    my_sec              : > D_FLASHA     PAGE = 1
    
    /* Allocate IQ math areas: */
       IQmath              : > FLASHC_D     PAGE = 0            /* Math Code */
       IQmathTables        : > IQTABLES,    PAGE = 0, TYPE = NOLOAD
    
       /* Uncomment the section below if calling the IQNexp() or IQexp()
          functions from the IQMath.lib library in order to utilize the
          relevant IQ Math table in Boot ROM (This saves space and Boot ROM
          is 1 wait-state). If this section is not uncommented, IQmathTables2
          will be loaded into other memory (SARAM, Flash, etc.) and will take
          up space, but 0 wait-state is possible.
       */
       /*
       IQmathTables2    : > IQTABLES2, PAGE = 0, TYPE = NOLOAD
       {
    
                  IQmath.lib<IQNexpTable.obj> (IQmathTablesRam)
    
       }
       */
       /* Uncomment the section below if calling the IQNasin() or IQasin()
          functions from the IQMath.lib library in order to utilize the
          relevant IQ Math table in Boot ROM (This saves space and Boot ROM
          is 1 wait-state). If this section is not uncommented, IQmathTables2
          will be loaded into other memory (SARAM, Flash, etc.) and will take
          up space, but 0 wait-state is possible.
       */
       /*
       IQmathTables3    : > IQTABLES3, PAGE = 0, TYPE = NOLOAD
       {
    
                  IQmath.lib<IQNasinTable.obj> (IQmathTablesRam)
    
       }
       */
    
       /* .reset is a standard section used by the compiler.  It contains the */
       /* the address of the start of _c_int00 for C Code.   /*
       /* When using the boot ROM this section and the CPU vector */
       /* table is not needed.  Thus the default type is set here to  */
       /* DSECT  */
       .reset              : > RESET,      PAGE = 0, TYPE = DSECT
       vectors             : > VECTORS     PAGE = 0, TYPE = DSECT
    
    }
    
    /*
    //===========================================================================
    // End of file.
    //===========================================================================
    */
    
    
    proj_lab10a.map.txt7484.proj_lab10a.txtto .txt due to limitations of the e2e forum).

    Can you please help me understand why the .txt file has a 0x50 address ?

    By the way, I've disabled the compiler optimization for the kernel .c files (all MotorWare projects come with an optimization level 2).

    Thanks a lot !

  • What linker command file are you using?

    You need to have a strictly flash application.

    Also, ESTOPs will not work without the debugger connected. If you are wishing to run this from standalone, then the ESTOPs will not halt the CPU. It will be ignored. You may need Exit Boot. or at least a branch to where you wish to begin executing after downloading the application.

    sal
  • Hi Sal,
    I've attached the command file. the name is "F28027F_wt_FlashAPI.cmd"
    I'm using a command file from the MotorWare projects, and I customized it a bit...
    I'm using a debugger, so I can see where the code stops. Eventually of course that I will remove the ESTOP when everything works perfectly...

    I'm not using the breakpoints since most of the project has high optimization level, which sometimes creates problems (well, at least I think it's because of the optimization level).

  • It needs to be a strictly flash application using a flash linker command file. You can see some examples in controlSUITE.

    You can check the map file to ensure that your application is in flash only.

    Thanks,
    sal
  • Ok, this is obvious. This is a strictly flash application.

    The .text section is in Flash...

    And the address where the kernel stopped is 0x50, which is the .stack address...

    Do you see any clues in the map file ?

  • It is not just .text that needs to be in flash. Everything needs to be originally loaded into flash.

    If you are getting a block address in RAM, then that means that some data is being loaded into RAM and that means that not all your data and program is in flash.

    sal
  • Hi Sal,
    Ok, I found the problem:
    I was filling up the stack for debugging reason with 0xABCD... So the linker created a memory map for this write....
    I removed it and it's ok now...

    Thanks a lot for your quick response!
  • No Problem! Glad you fixed it. Please verify my previous response to close the thread.

    Thanks,
    sal
  • I would like to go further and make the kernel and PC-side more robust. I will open a new thread after implementing and testing.
    I'm thinking of 2 things to add:
    1. The PC should add a checksum in the packet it sends. (maybe after DestAddr). That way we can check the checksum before writing to flash. If the checksum doesn't pass, the PC will re-send the last packet.
    2. Check the destination address before writing to flash...

    3. Any other ideas ? My issue is that I'm going to use one flash sector to be used as EEPROM, and the device has only 4 (little) sectors (compared to the 28069 which I'm using today...), so I cannot really build a redundant code system...

    Thanks
  • Check out the Serial Flash Programmer Application Note I posted earlier. Some of those things you are looking for are implemented in the "Kernel B" for F2807x, F2837xS, and F2837xD.

    You can look at the serial flash programmer and the code in f021_downloadImage.cpp and the flash kernels in controlSUITE for those devices to get an idea of how it looks to implement that. You should be able to port that code to be used with the F2802x.

    Yes, please open another thread for these separate issues.

    sal