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.

how write to cc2530 flash

Other Parts Discussed in Thread: CC2530, SIMPLICITI

i want to write some of my data  into cc2530 flash, through sram.  i had tried several times to do this, but with a few informationin  in cc2530 user guide, i couldnt do this.

i thankful, and very appreciated for any sample codes a soon as possible ,..

thank you.

  • Hello,

    Thanks for your usefull guide.I studied that page. but i have (Zstack-cc2530-2.4.0-1.4.0.exe). does it work for my need?

    also, i had designed  my own board with cc2530, and don't use any development kit or peripheral modules. does this procedure respond for my own board? beacuse whenever i open Zstack and run its sample projects, and want to debug these projects in IAR, a window has be opened and this warning imerged: "Target selection". i don't know how deal with this problem. however, i had written codes on my own, for various sections of cc2530, and fortunetly i could initialize the Radio or other parts of this IC, without any using from Zstack or SimpliciTi. now, i  need to store some of my data in flash memory. i had studied chapter 6(flash controller) from CC230 several times. but it doesn't work for me. how can i use this possibility of Zstack(Bootloader/Boot.eww) in my own codes, and is it enough for flash manipulation(read/write/erase operation).?

    Very thanks and appreciate Mr Jim Noxon.

    David.

     

     

     

  • I was trying point you to the routines within the boot loader code which write to the flash.  These should be valid for storing data at run time as well.  Note that you must erase a full block of flash but you can write one word at a time.  Your code will need to take this into account when deciding where to put your non-volatile data as well as how to update it.

    The target selection window you are seeing in IAR is because it doesn't see any target to download code to in order to start debugging on a hardware target.  You need to have the debug interface on your board so you can connect something like a CCDebugger that will allow you to download your initial version of code (or the serial boot loader or something similar).  The CC2530 is not shipped with any form of boot loader pre-installed and the debugging interface is the only way to get the initial code load onto it.

    Jim Noxon

  • Hello,

     Thanks alot,

     excuse me.but i have some dificulties with flash access, and need your helps some more. i fellow the first section in "CC253x serial boot loader" page in IAR. and,  i found "CC2530SB.hex"  in the "Projects\zstack\Utilities\BootLoad\CC2530\boot.eww" path. but i didn't understood how apply the changes that said in the   "SBL Compatible Application Code Image" section, for my own code. which steps is needed for  my code, to be compatible with SBL.

    all my need is: write a few bytes of data that come from RXFIFO somewhere in the flash, after programming the board with CCDebugger, and  it be possible to  change these stored bytes by a given incoming data from RXFIFO.( a given data).is it possible only by Boot loader? by means, isn't DMAflashwrite or ...  procedure needed for writting or changing the given stored data in one  location of  flash ?

    I am in trouble, and hope that be able to solve this problem by your help.

    Thank you very much,  Mr Noxon.

    David.

     

  • The serial boot loader is not what you need in its entirety, but it does have the routines within it that can erase and write segments of flash and they have already been debugged.  What you will want to do is to utilize those parts of the serial boot load code to accomplish writing to the flash.  Once you get your radio code running then you will create a special type of packet that your code will recognize needs to be passed to the flash routines to update the parts of flash you want to modify.

    Jim Noxon

  • Hello,

    excuse me for inconvenience

    so at first, do i should download the hex file "CC2530SB.hex" that is created by running Boot Load code? i have attached boot load code, at the bellow. which parts of the serial boot load code should be used for writing into flash?do i apply the following modifications in IAR(for  my  own codes)?:

    1-SBL Compatible Application Code Image

    2-Download a New Application Image via SBL

    3-Customising the bootload process

    4-Customising the Application to Reset

    5-Remove long boot delay

    6-Bypass the CRC check to speed up debug

    7-SMartRF Programmer Compatible Image

    some thing  is unknown for me, where do i determine, that one given byte of my data that come from RXFIFO should go to flash? now in my code i get packets from RXFIFO, and i read them from RFD register and put them in a defined buffer. then i want to put some of these bytes into flash.  i saw some (.h) files that included for (sb_main.c) in IAR such as (hal_flash.h,hal_dma.h, hal_types_h, hal_mcu.h, and ....). do i call any sobroutine of these included files in my codes or in Boot Load code? which of those?

    Thanks, special respect for your assistance. sincerely.

    excuse me  Mr Noxon.

    David.

    ************

    [sb_main.c]

    #include "comdef.h"
    #include "hal_board_cfg.h"
    #include "hal_adc.h"
    #include "hal_dma.h"
    #include "hal_flash.h"
    #include "hal_types.h"
    #include "sb_exec.h"
    #include "sb_main.h"

    /* ------------------------------------------------------------------------------------------------
     *                                          Constants
     * ------------------------------------------------------------------------------------------------
     */

    // The IAR C-Stack initializer value: 0xCD.
    #if !defined SB_STACK_VALUE
    #define SB_STACK_VALUE  0xCD
    #endif
    // Not zero and not SB_STACK_VALUE.
    #if !defined SB_MAGIC_VALUE
    #define SB_MAGIC_VALUE  0xF5
    #endif

    /* ------------------------------------------------------------------------------------------------
     *                                           Macros
     * ------------------------------------------------------------------------------------------------
     */

    #define SB1_PRESS  (P0_1 != 0)
    #define SB2_PRESS  (P2_0 != 0)

    #if HAL_LED
    #define SB_TURN_OFF_LED1()  HAL_TURN_OFF_LED1()
    #define SB_TURN_ON_LED1()   HAL_TURN_ON_LED1()
    #define SB_TOGGLE_LED1()    HAL_TOGGLE_LED1()
    #define SB_TURN_OFF_LED2()  HAL_TURN_OFF_LED2()
    #define SB_TURN_ON_LED2()   HAL_TURN_ON_LED2()
    #define SB_TOGGLE_LED2()    HAL_TOGGLE_LED2()
    #else
    #define SB_TURN_OFF_LED1()
    #define SB_TURN_ON_LED1()
    #define SB_TOGGLE_LED1()
    #define SB_TURN_OFF_LED2()
    #define SB_TURN_ON_LED2()
    #define SB_TOGGLE_LED2()
    #endif

    /* ------------------------------------------------------------------------------------------------
     *                                       Global Variables
     * ------------------------------------------------------------------------------------------------
     */

    halDMADesc_t dmaCh0;

    /* ------------------------------------------------------------------------------------------------
     *                                       Local Variables
     * ------------------------------------------------------------------------------------------------
     */

    /* ISR's implemented in the boot loader must be able to quickly determine whether to jump to the
     * boot code handlers or the run code handlers. So mark the bottom of the C call stack space with
     * a special value. Since the boot code linker file starts the C call stack space one byte higher
     * than the run code, the IAR generated initialization code does not initialize this byte;
     * but the boot code does - marking it with the magic value.
     */
    #pragma location="SB_MAGIC_SPACE"
    volatile __no_init uint8 magicByte;

    /* ------------------------------------------------------------------------------------------------
     *                                       Local Functions
     * ------------------------------------------------------------------------------------------------
     */

    static void vddWait(uint8 vdd);
    static void sblInit(void);
    static void sblExec(void);
    static uint8 sblWait(void);

    // Saving code space by not using the _hal_uart.c API and directly including the low level drivers.
    #include "_hal_uart_isr.c"

    /**************************************************************************************************
     * @fn          main
     *
     * @brief       ISR for the reset vector.
     *
     * input parameters
     *
     * None.
     *
     * output parameters
     *
     * None.
     *
     * @return      None.
     **************************************************************************************************
     */
    void main(void)
    {
      sblInit();

      if (sbImgValid())
      {
        if (sblWait())
        {
          HalUARTUnInitISR();
          // Simulate a reset for the Application code by an absolute jump to location 0x2000.
          asm("LJMP 0x2000\n");
          HAL_SYSTEM_RESET();
        }
      }

      sblExec();
      HAL_SYSTEM_RESET();
    }

    /**************************************************************************************************
     * @fn          vddWait
     *
     * @brief       Loop waiting for 16 reads of the Vdd over the requested limit.
     *
     * input parameters
     *
     * @param       vdd - Vdd level to wait for.
     *
     * output parameters
     *
     * None.
     *
     * @return      None.
     **************************************************************************************************
     */
    static void vddWait(uint8 vdd)
    {
      uint8 cnt = 16;

      do {
        do {
          ADCCON3 = 0x0F;
          while (!(ADCCON1 & 0x80));
        } while (ADCH < vdd);
      } while (--cnt);
    }

    /**************************************************************************************************
     * @fn          sblInit
     *
     * @brief       Initialization for SBL.
     *
     * input parameters
     *
     * None.
     *
     * output parameters
     *
     * None.
     *
     * @return      None.
     **************************************************************************************************
     */
    static void sblInit(void)
    {
      halUARTCfg_t uartConfig;
      HAL_BOARD_INIT();
      vddWait(VDD_MIN_RUN);
      magicByte = SB_MAGIC_VALUE;

      /* This is in place of calling HalDmaInit() which would require init of the other 4 DMA
       * descriptors in addition to just Channel 0.
       */
      HAL_DMA_SET_ADDR_DESC0(&dmaCh0);

      HalUARTInitISR();
      uartConfig.configured           = TRUE;
      uartConfig.baudRate             = HAL_UART_BR_115200;
      uartConfig.flowControl          = FALSE;
      uartConfig.flowControlThreshold = 0;  // CC2530 by #define - see hal_board_cfg.h
      uartConfig.rx.maxBufSize        = 0;  // CC2530 by #define - see hal_board_cfg.h
      uartConfig.tx.maxBufSize        = 0;  // CC2530 by #define - see hal_board_cfg.h
      uartConfig.idleTimeout          = 0;  // CC2530 by #define - see hal_board_cfg.h
      uartConfig.intEnable            = TRUE;
      uartConfig.callBackFunc         = NULL;
      HalUARTOpenISR(&uartConfig);
    }

    /**************************************************************************************************
     * @fn          sblExec
     *
     * @brief       Infinite SBL execute loop that returns upon receiving a code enable.
     *
     * input parameters
     *
     * None.
     *
     * output parameters
     *
     * None.
     *
     * @return      None.
     **************************************************************************************************
     */
    static void sblExec(void)
    {
      uint32 dlyCnt = 0;
      vddWait(VDD_MIN_NV);
      HAL_ENABLE_INTERRUPTS();

      while (1)
      {
        if (dlyCnt++ & 0x4000)
        {
          SB_TOGGLE_LED1();
        }

        if (sbExec())
        {
          break;
        }
      }

      SB_TURN_ON_LED1();
      SB_TURN_ON_LED2();
      // Delay to allow the SB_ENABLE_CMD response to be flushed.
      for (dlyCnt = 0; dlyCnt < 0x40000; dlyCnt++)
      {
        asm("NOP");
      }
    }

    /**************************************************************************************************
     * @fn          sblWait
     *
     * @brief       A timed-out wait loop that exits early upon receiving a force code/sbl byte.
     *
     * input parameters
     *
     * None.
     *
     * output parameters
     *
     * None.
     *
     * @return      TRUE to run the code image, FALSE to run the SBL.
     **************************************************************************************************
     */
    static uint8 sblWait(void)
    {
      uint32 dlyCnt = 0x260000;
      uint8 rtrn = FALSE;
      HAL_ENABLE_INTERRUPTS();

      while (1)
      {
        uint8 ch;

        if (HalUARTReadISR(&ch, 1))
        {
          if (ch == SB_FORCE_BOOT)
          {
            break;
          }
          else if (ch == SB_FORCE_RUN)
          {
            dlyCnt = 0;
          }
        }

       // if (SB1_PRESS)
        //{
          break;
        //}

        //if (SB2_PRESS || (dlyCnt-- == 0))
        //{
         // rtrn = TRUE;
         // break;
        //}

        // RR-xing LED display while waiting.
        if (dlyCnt & 0x2000)
        {
          SB_TURN_OFF_LED2();
          SB_TURN_ON_LED1();
        }
        else
        {
          SB_TURN_OFF_LED1();
          SB_TURN_ON_LED2();
        }
      }

      HAL_DISABLE_INTERRUPTS();
      SB_TURN_OFF_LED1();
      SB_TURN_OFF_LED2();

      return rtrn;
    }

    /**************************************************************************************************
     * @fn          URXx/UTXx_VECTOR
     *
     * @brief       Intercept the USART0 ISR's here and consume locally if in boot loader, or forward
     *              to a valid run-code image.
     *
     * input parameters
     *
     * None.
     *
     * output parameters
     *
     * None.
     *
     * @return      None.
     **************************************************************************************************
     */
    HAL_ISR_FUNCTION( halUart0RxIsr, URX0_VECTOR )
    {
      if (magicByte == SB_STACK_VALUE)
      {
        void (*rxIsr)(void);
        rxIsr = (void (*)(void))0x2013;
        rxIsr();
      }
      else if (magicByte == SB_MAGIC_VALUE)
      {
        halUartRxIsr();
      }
      else
      {
        asm("NOP");  // Not expected.
      }
    }

    HAL_ISR_FUNCTION( halUart0TxIsr, UTX0_VECTOR )
    {
      if (magicByte == SB_STACK_VALUE)
      {
        void (*txIsr)(void);
        txIsr = (void (*)(void))0x203B;
        txIsr();
      }
      else if (magicByte == SB_MAGIC_VALUE)
      {
        halUartTxIsr();
      }
      else
      {
        asm("NOP");  // Not expected.
      }
    }

  • The hex file is simply a pre-compiled version of the boot loader.  From your original post, I don't think you are wanting the entire boot loader so it seems you should ignore the hex file completely.  You need to pick apart the source code to find those portions of it you can use to write/erase flash so you don't have to re-invent this part of it.  If you try to use the boot loader in its entirety, you will never achieve your goal, at least the one I understand you want.

    Jim Noxon

  • Hello,

    excuse me again,

    so, is it possible to integrate  my own codes  in serial boot loader main code ( my means that i write my own codes and routines in the main of Boot Loader source code)?

    and then call the following subroutines for flash manipulation? is these all i need for flash write/read? or something different?

    void HalFlashErase(uint8 pg);

    void HalFlashWrite(uint16 addr, uint8 *buf, uint16 cnt);

    void HalFlashRead(uint8 pg, uint16 offset, uint8 *buf, uint16 cnt);

    i somewhat confused with steps that have been listed in the (http://processors.wiki.ti.com/index.php/CC253x_Serial_Boot_Loader) page. do i apply all the steps of that page for mine?

    by studing the (Zstack/utilities/Boot Load)codes  and serial boot loader webpage i have this perspective: boot loader source code(sb_main.c)file  that i attached in my previous post, has a critical role for flash manipulation. beacuse at first time we can't write/read flash without using it, is this derivation true?? i need clarification.

    respect and Thanks for you.

    David.

     

     

  • I don't think you want to integrate your code with the serial boot loader, but rather I think you want to take the hal_flash.c file and possibly a few others it requires to compile and integrate them into your code.  There is too many other things going on with the serial boot load process that it doesn't make sense to use the whole project simply to work with the flash but because there are routines within it that accomplish what you need, you can pull them out of the serial boot loader project and utilize them in your own project.

    Yes, the three routines you are referring to are the ones you will want to use.  I don't think you want to apply any of the instructions on the wiki page, just take the code you need.

    It seems like we have moved significantly away from merely wanting to write some data to flash, or is there something else going on that has changed the context of what you originally were asking to do?

    Jim Noxon

  • Hello,

    my project demand the  storing of a few data in an empty location of flash, that can be remained whenever the power of board is off. I was confident that such improved chip from TI has this possibility, but i didn't know how deal with it,sincerely. i had used  your instructive guidance,exactly. and i guessed that  it is the best way to solve my problem.thanks alot.

    what's the concept of this?:

    "There is too many other things going on with the serial boot load process that it doesn't make sense to use the whole project simply to work with the flash but because there are routines within it that accomplish what you need, you can pull them out of the serial boot loader project and utilize them in your own project."

    Are these needed routines only the ones that i found them in [hal_flash.c], which i included them in previous post? so do i call them in the main of my codes? is this troubleshooting.

     thanks.

    David

  • david moein said:
    my project demand the  storing of a few data in an empty location of flash, that can be remained whenever the power of board is off. I was confident that such improved chip from TI has this possibility

    This is exactly what I originally though you were asking to do

    ------------------------------------------------------------------------------------------------------------------------------------------------------

    david moein said:

    what's the concept of this?:

    "There is too many other things going on with the serial boot load process that it doesn't make sense to use the whole project simply to work with the flash but because there are routines within it that accomplish what you need, you can pull them out of the serial boot loader project and utilize them in your own project."

    The boot loader can write to flash.  It also has a command handler which interfaces with a host pc, uart driver, button driver, remapped set of interrupt vectors, modified linker command file for alternative placement of the boot loader and user code, the ability to detect a valid code image, and finally information representing the entry point to user code.  All of which you don't need if all you want to do is "write to flash".  This was why I was confused as to why you were trying to fit your code into the boot loader project.

    ------------------------------------------------------------------------------------------------------------------------------------------------------

    david moein said:
    Are these needed routines only the ones that i found them in [hal_flash.c], which i included them in previous post? so do i call them in the main of my codes?

    Yes, you only need to take the functions from hal_flash.c and utilize them in your code.

    ------------------------------------------------------------------------------------------------------------------------------------------------------

    Jim Noxon

  • Excuse me for all inconvenience.

    I didn't had special reason for integrating my codes into serial boot loader. it was my point of view for solving this problem. your explanation made me clarify.

    based on my studies on cc2530 user guide, i guess that for writing into flash, at first we should erase a page in the flash, and i have to be confident that this page of flash isn't occupied by CCdebugger  hexa codes. doesn't it?

    for instance, when i want to write 4 bytes in flash  at   the start  address of  0xaa00, act as bellow:

    uint8 *data[]={putting 4 bytes that come from RFD into this pre-defined buffer};

    EA=0; // global interrupt disabling

    HalFlashErase(uint8 pg);   //     FADDRH = pg * (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE / 256);// pg=??

    while(FCTL&0x80); //   make sure that erase operation is completed

    HalFlashWrite(0xaa00, data, 1);// cnt=1(  Number of 4-byte blocks to write)

    EA=1; // global interrupt enabling

    ......................................................................

    does  this procedure is correct?

    1-is the [uint16 addr] the start address for writing operation? and do i have chosen that  truly?

    2- and if flash erasing is needed before the writing, so how do i select correct page?

    3-I think that the flash writing procedure that had been provided in the (hal_flash.c) works based on DMA, do i have to disable global interrupt at first and able it at the end of writing operation?

    thanks alot Mr Noxon.

    best regard.

    David.

     

     

     

     

  • There is no inconvience in helping you.  All are welcom to the E2E forums.  I apologize if my words are unclear or have mislead you.

    I believe you are on the right path now.  Your explanation of what you intend to do makes sense.

    For your questions,

    1) The uint16 is the start address divided by 4.  Since you must write the flash 4 bytes at a time, you must write to the flash on a 4 byte address boundary.  Thus the uint16 is actually address bits 17..2 with address bits 1..0 assumed to be zero.  Note that the address bits 17..2 will fit within a uint16 after dividing by 4.  Therefore, to write 4 bytes starting at address 0xAA00, pass the value of 0x2A80 for the uint16 addr parameter.

    2) The page to erase will be the most significant 7 bits of the address you want to write to.  Thus if you want to write to 0xAA00, the page to erase will be 0x2A80 & 0xFE00 = 0x2A00 which is code address 0xA800 and is all of the flash from 0xA800-0xAFFF.

    3) no, you don't have to disable interrupts but you want to make sure any interrupts don't access the page while it is being erased or written.  If you cannot be sure of this then disabling interrupts would be a good idea.  The code itself simply waits for the DMA to complete by polling its status so interrupts are not part of the flash write code.

    Jim Noxon

  • Hello,

    i have thanks and appreciate so much, beacuse of your instructive guiadances.

    i have been understood, so i will try your suggestions, and hope to find the clue of problem.

    special thanks for you and your corporation useful services.

    David.

  • Hello,

    i , and implemented them in my codes. one issue that i am concerned about it, is finding  the location of flash that is occuppied by ccdebugger HEXA code.

    1- how it's possible to indicate the spaces in flash  that is occupied by CCDebugger? and then,surely start to write the data from which address in flash that is empty?

    2- for writing those  4 bytes of my data from the start address of 0xaa00, and then reading these 4 bytes and saving them into a pre-defined buffer i act as bellow:

            uint8 temp[4];
           uint8 data[]={0xff,0xff,0x00,0x00};
           HalFlashErase(2A00); // erase from 0xA800-0xAFFF pages.
           while(FCTL&0x80); //   make sure that erase operation is completed
           HalFlashWrite(0x2A80, data, 1);// cnt=1(  Number of 4-byte blocks to write)// addr=flashaddr/4
           while(FCTL&0x80); //   make sure that write operation is completed
           HalFlashRead(uint8 pg, uint16 offset, temp, 4);

    2- does it work in practical? in  the  'HalFlashRead" function, how do i allocate  true value for "pg" and "offset"  sub-fields? 

     i have set  the variable fields of write and erase functions with their defined values, as bellow:

    *************************flash write*******using DMA channel0 for writing******************************
     */
    void HalFlashWrite(uint16 addr, uint8 *buf, uint16 cnt)
    {
    #if (defined HAL_DMA) && (HAL_DMA == TRUE)
      halDMADesc_t *ch = HAL_NV_DMA_GET_DESC();

      HAL_DMA_SET_SOURCE(ch, buf);
      HAL_DMA_SET_DEST(ch, &FWDATA);
      HAL_DMA_SET_VLEN(ch, 0);
      HAL_DMA_SET_LEN(ch, (cnt * 4));
      HAL_DMA_SET_WORD_SIZE(ch, 0);
      HAL_DMA_SET_TRIG_MODE(ch, 0);
      HAL_DMA_SET_TRIG_SRC(ch, 18);
      HAL_DMA_SET_SRC_INC(ch, 1);
      HAL_DMA_SET_DST_INC(ch, 0);
      // The DMA is to be polled and shall not issue an IRQ upon completion.
      HAL_DMA_SET_IRQ(ch, 0);
      HAL_DMA_SET_M8( ch, 0);
      HAL_DMA_SET_PRIORITY(ch,2);
      HAL_DMA_CLEAR_IRQ(0);
      HAL_DMA_ARM_CH(0); // ch is set to 0

      FADDRL = (uint8)addr;
      FADDRH = (uint8)(addr >> 8);
      FCTL |= 0x02;         // Trigger the DMA writes.
      while (FCTL & 0x80);  // Wait until writing is done.
    #endif
    }
    //********************page read**************************************************************

    void HalFlashRead(uint8 pg, uint16 offset, uint8 *buf, uint16 cnt)
    {
      // Calculate the offset into the containing flash bank as it gets mapped into XDATA.
      uint8 *pData = (uint8 *)(offset + HAL_FLASH_PAGE_MAP) +
                     ((pg % HAL_FLASH_PAGE_PER_BANK) * HAL_FLASH_PAGE_SIZE);
      uint8 memctr = MEMCTR;  // Save to restore.

    #if !defined HAL_OAD_BOOT_CODE //????
      halIntState_t is;
    #endif

      pg /= HAL_FLASH_PAGE_PER_BANK;  // Calculate the flash bank from the flash page.

    #if !defined HAL_OAD_BOOT_CODE  //????
      HAL_ENTER_CRITICAL_SECTION(is);
    #endif

      // Calculate and map the containing flash bank into XDATA.
      MEMCTR = (MEMCTR & 0xF8) | pg;

      while (cnt--)
      {
        *buf++ = *pData++;
      }

      MEMCTR = memctr;

    #if !defined HAL_OAD_BOOT_CODE  //????
      HAL_EXIT_CRITICAL_SECTION(is);
    #endif
    }

    //*****************************************************

    3-for my need, do i use that parts of read routine, which i had marked them with(????) in front of them? i think that, these parts of "halflashread" are related to boot load, and i can ignore them. i'm not sure.

    thank you so much for your help.

    David.

     

     

  • Hello,

    Your recommendation  was helpful, and i  implemented them in my codes. one issue that i am concerned about it, is finding  the location of flash that is occuppied by ccdebugger HEXA code.

    1- how it's possible to indicate the spaces in flash  that is occupied by CCDebugger? and then,surely start to write the data from which address in flash that is empty?

    2- for writing those  4 bytes of my data from the start address of 0xaa00, and then reading these 4 bytes and saving them into a pre-defined buffer i act as bellow:

            uint8 temp[4];
           uint8 data[]={0xff,0xff,0x00,0x00};
           HalFlashErase(2A00); // erase from 0xA800-0xAFFF pages.
           while(FCTL&0x80); //   make sure that erase operation is completed
           HalFlashWrite(0x2A80, data, 1);// cnt=1(  Number of 4-byte blocks to write)// addr=flashaddr/4
           while(FCTL&0x80); //   make sure that write operation is completed
           HalFlashRead(uint8 pg, uint16 offset, temp, 4);

    2- does it work in practical? in  the  'HalFlashRead" function, how do i allocate  true value for "pg" and "offset"  sub-fields?

     i have set  the variable fields of write and erase functions with their defined values, as bellow:

    *************************flash write*******using DMA channel0 for writing******************************
     */
    void HalFlashWrite(uint16 addr, uint8 *buf, uint16 cnt)
    {
    #if (defined HAL_DMA) && (HAL_DMA == TRUE)
      halDMADesc_t *ch = HAL_NV_DMA_GET_DESC();

      HAL_DMA_SET_SOURCE(ch, buf);
      HAL_DMA_SET_DEST(ch, &FWDATA);
      HAL_DMA_SET_VLEN(ch, 0);
      HAL_DMA_SET_LEN(ch, (cnt * 4));
      HAL_DMA_SET_WORD_SIZE(ch, 0);
      HAL_DMA_SET_TRIG_MODE(ch, 0);
      HAL_DMA_SET_TRIG_SRC(ch, 18);
      HAL_DMA_SET_SRC_INC(ch, 1);
      HAL_DMA_SET_DST_INC(ch, 0);
      // The DMA is to be polled and shall not issue an IRQ upon completion.
      HAL_DMA_SET_IRQ(ch, 0);
      HAL_DMA_SET_M8( ch, 0);
      HAL_DMA_SET_PRIORITY(ch,2);
      HAL_DMA_CLEAR_IRQ(0);
      HAL_DMA_ARM_CH(0); // ch is set to 0

      FADDRL = (uint8)addr;
      FADDRH = (uint8)(addr >> 8);
      FCTL |= 0x02;         // Trigger the DMA writes.
      while (FCTL & 0x80);  // Wait until writing is done.
    #endif
    }
    //********************page read**************************************************************

    void HalFlashRead(uint8 pg, uint16 offset, uint8 *buf, uint16 cnt)
    {
      // Calculate the offset into the containing flash bank as it gets mapped into XDATA.
      uint8 *pData = (uint8 *)(offset + HAL_FLASH_PAGE_MAP) +
                     ((pg % HAL_FLASH_PAGE_PER_BANK) * HAL_FLASH_PAGE_SIZE);
      uint8 memctr = MEMCTR;  // Save to restore.

    #if !defined HAL_OAD_BOOT_CODE //????
      halIntState_t is;
    #endif

      pg /= HAL_FLASH_PAGE_PER_BANK;  // Calculate the flash bank from the flash page.

    #if !defined HAL_OAD_BOOT_CODE  //????
      HAL_ENTER_CRITICAL_SECTION(is);
    #endif

      // Calculate and map the containing flash bank into XDATA.
      MEMCTR = (MEMCTR & 0xF8) | pg;

      while (cnt--)
      {
        *buf++ = *pData++;
      }

      MEMCTR = memctr;

    #if !defined HAL_OAD_BOOT_CODE  //????
      HAL_EXIT_CRITICAL_SECTION(is);
    #endif
    }

    //*****************************************************

    3-for my need, do i use that parts of read routine, which i had marked them with(????) in front of them? i think that, these parts of "halflashread" are related to boot load, and i can ignore them. i'm not sure.

    thank you so much for your help.

    David.

     

     

  • The code you are questioning is simply disabling the global interrupts during the flash read routine.  This is done because the flash bank with the target address may need to be swapped into upper memory in order for the processor to read it.  If you leave interrupts enabled, you may end up jumping to code which is no longer where the compiler expects it to be.

    Another thing you will want to do is to make sure you place the flash read routine in in bank 0 so that it can be executed from lower memory.  This way you don't accidentally swap out the code you are executing.

    With knowing where you can actually store your data, refer to the map file generated by the compiler.  You may need to turn on this option.

    Probably the best way to manage it would be to modify the linker command file to create a specific place in flash for you data.  That way you don't need to worry about a change in your code suddenly causing your space in flash to get used.

    Jim Noxon

  • 1680.code memory space.txt

    Hello,

    I activate the Map in the  compiler (Linker>>list>>General linker listing) and after debugging my own project, check mark the "Memory" in  the "view" meno.

    by including all flash-related header files, here is all of a project that i want to test flash writing:

    ...........................................................................................

    #include <iocc2530.h>
    #include "stdio.h"
    #include "hal_board_cfg.h"
    #include "hal_dma.h"
    #include "hal_flash.h"
    #include "hal_mcu.h"
    #include "hal_types.h"
    #include "hal_defs.h"

    void HalFlashRead(uint8 pg, uint16 offset, uint8 *buf, uint16 cnt);
    void HalFlashWrite(uint16 addr, uint8 *buf, uint16 cnt);
    void HalFlashErase(uint8 pg);
    void main(void)
    {
    // writing to 0xaa00 flash address

    HalFlashErase(0x2a00); // erase from 0xA800-0xAFFF pages.
    while(FCTL&0x80); //   make sure that erase operation is completed
    HalFlashWrite(0x2a80, "1234", 1);// cnt=1(  Number of 4-byte blocks to write)// addr=flashaddr/4
    while(FCTL&0x80); //   make sure that write operation is completed
     
    }

    ...................................................

    is it possible to check the written section of flash in compiler without any connection to hardware? beacuse i have searched for my data in the "Memory" window that's apears in the bottom of IAR compiler. but i don't find any thing in "Code" memory space except the instruction codes.[i have attached code memory content].

    Exactly, i don't Know what's wrong for me. Are my codes  incomplete or my compiler settings? I have been involved with this issue too. I do not know the solution.

    i Appreciate any more help to solve this problem.

    Thanks very much.

    David.

  • It sounds to me like you are testing your code in the simulator environment.  In this case, you will not see any updates to the flash as the simulator does not model the flash for write updates.  Therefore, you will need to test your code directly on real hardware to verify it's operation.  In this case, after the flash writes are complete, you should be able to see the updates in the flash memory by simply refreshing the memory window displaying the region of flash you wrote to.

    Jim Noxon

  • Hello,

    Excuse me, what's your means by this :

    "after the flash writes are complete, you should be able to see the updates in the flash memory by simply refreshing the memory window displaying the region of flash you wrote to."

    1-is it possible only in the "flash programmer" software, by checking mark the "Read flash into hex-file" option after programming the hardware by it??

    2-After i had written 4 bytes at the start address of 0XAA00 in the flash, i want to read them for using them in my applications. I set the values of "HalFlashRead" as bellow:

    uint8 *RData[4];

    HalFlashRead(0x15, 0x0200, RData, 4);

    do i set these values correctly? i don't confident about them.

    3- my another question  is about using  these instructions in the "HalFlashRead":

    #if !defined HAL_OAD_BOOT_CODE
      halIntState_t is;
    #endif

    #if !defined HAL_OAD_BOOT_CODE
      HAL_ENTER_CRITICAL_SECTION(is);
    #endif

    #if !defined HAL_OAD_BOOT_CODE
      HAL_EXIT_CRITICAL_SECTION(is);
    #endif

    is it needed for my application?

    Thank you again so much for your assistance.

    David.

  • Hello,

    Thank you so much, Mr Noxon. I implemented your devise for flash read/write,and successfully could access to flash for my purpose.

    Thanks alot for all your guidances,

    David.

  • I apologize for missing your previous post.  It would appear you were able to correct your problems on your own and now have code that operates correctly.  This is good to hear.

    Congratulations to you on your success!

    Jim Noxon

  • Hello, Mr. David Moein
    I wonder how you made ​​the process of writing and reading in flash memory. I will be grateful if you can provide a sample of your code.

    Thanks,

    Luan