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.

Sample code for writing and reading Flash in CC2530...

Other Parts Discussed in Thread: CC2530

Hi,

I have been trying out to access the Flash memory (thro' CPU) of the CC2530 SoC. I tried with the possible changes as per the User guide of CC2530 but could not succeed.

Can someone help me out with a sample code for the same without using the DMA...

Regards,

Vinoth

  • Hello, I also have have problems to write the CC2530  flash, I'm using DMA method.

    the problem is : when running this code in debugger , it's ok. the write function seems ok. but when run in standalone, the CPU will stuck at waiting DMA complete.

    here is my code:

    /* One whole page of flash memory is to be reserved, i.e., 1 KiB. */
    #define PAGE_SIZE 2048        //1024

    /* String length (exluding the terminal '\0'). */
    #define DATA_AMOUNT 36


    /*******************************************************************************
    * LOCAL VARIABLES
    */

    /* The "string" to be written to flash ('\0' not included). */
    static __xdata char data[DATA_AMOUNT] = "FLash Controller TEST oK!! GREAT!! \r";


    /* String that is filled by reading from the data area that was written to in
     * flash. Can be used to debug the example, since the debugger may suggest that
     * nothing was written to flash.
     */
    static char writeCheck[DATA_AMOUNT];
    /* The area in flash where the string (data written to flash) will be placed.
     * If not placed at an even absolute location, the address might be odd (e.g.
     * 0x4401). Since flash is addressed in words, writing would start at one byte
     * before (or after) the address unless explicit action is made to avoid this.
     * Page 17 will be used, so the address is 0x4400 ( = 1024 * 17).
     */
     // 2048 * 15 = 0x7800; last page
    __no_init const char __code flashDataAddr[PAGE_SIZE] @ 0x7800;

    /* DMA configuration descriptor used for flash write. */
    static __xdata DMA_DESC dmaConfig0;


    void test_flashWrite(  void)
    {
        /* Configure DMA channel 0. Settings:
         * SRCADDR: address of the data to be written to flash (increasing).
         * DESTADDR: the flash controller data register (fixed), so that the
         *     flash controller will write this data to flash.
         * VLEN: use LEN for transfer count.
         * LEN: equal to the number of bytes to be transferred.
         * WORDSIZE: each transfer should transfer one byte.
         * TMODE: should be set to single mode (see datasheet, DMA Flash Write).
         *     Each flash write complete will re-trigger the DMA channel.
         * TRIG: let the DMA channel be triggered by flash data write complete
               (trigger number 18). That is, the flash controller will trigger the
               DMA channel when the Flash Write Data register, FWDATA, is ready to
               receive new data.
         * SRCINC: increment by one byte.
         * DESTINC: fixed (always write to FWDATA).
         * IRQMASK: disable interrupts from this channel.
         * M8: 0, irrelevant since we use LEN for transfer count.
         * PRIORITY: high.
         */
       
          
        EA  = 0;
       
        dmaConfig0.SRCADDRH  = ((uint16) data >> 8) & 0x00FF;
        dmaConfig0.SRCADDRL  = (uint16)data & 0x00FF;

        dmaConfig0.DESTADDRH = (((uint16)&FWDATA) >> 8) & 0x00FF;
        dmaConfig0.DESTADDRL = ((uint16)&FWDATA) & 0x00FF;
        dmaConfig0.VLEN      = DMA_VLEN_USE_LEN;
        dmaConfig0.LENH      = (DATA_AMOUNT>>8) & 0x00FF;
        dmaConfig0.LENL      = DATA_AMOUNT & 0x00FF;
        dmaConfig0.WORDSIZE  = DMA_WORDSIZE_BYTE;
        dmaConfig0.TMODE     = DMA_TMODE_SINGLE;
        dmaConfig0.TRIG      = DMA_TRIG_FLASH;
        dmaConfig0.SRCINC    = DMA_SRCINC_1;
        dmaConfig0.DESTINC   = DMA_DESTINC_0;
        dmaConfig0.IRQMASK   = DMA_IRQMASK_DISABLE;
        dmaConfig0.M8        = DMA_M8_USE_8_BITS;
        dmaConfig0.PRIORITY  = DMA_PRI_HIGH;


        /* The DMA configuration data structure may reside at any location in
         * unified memory space, and the address location is passed to the DMA
         * through DMA0CFGH:DMA0CFGL.
         */

        /* Waiting for the flash controller to be ready */
        //write("Waiting for FCTL & FCTL_BUSY 1 \r");
        while (FCTL & FCTL_BUSY);
          
       // page size: 2048; select the flash page via FADDRH[7:1] bits
        FADDRH =(uint16) &flashDataAddr >> 10; //8;
        FADDRL = ((uint16)&flashDataAddr>>2 ) & 0x00FF;
           
        /* Erase the page that will be written to. */
        //halFlashStartErase();
       
        /* Erase one flash page */
            EA = 0; /* disable interrupts */
            while (FCTL & 0x80); /* poll FCTL.BUSY and wait until flash controller is ready */
            FADDRH = 15 << 1;       /* select the flash page via FADDRH[7:1] bits */
            FCTL |= 0x01; /* set FCTL.ERASE bit to start page erase */
            while (FCTL & 0x80); /* optional: wait until flash write has completed (~20 ms) */
            //EA = 1; /* enable interrupts */

            //write("wait DMA \r");
           
        DMA0CFGH = (((uint16)&dmaConfig0) >> 8) & 0x00FF;
        DMA0CFGL = ((uint16)&dmaConfig0) & 0x00FF;
           
        /* Arm the DMA channel, so that a DMA trigger will initiate DMA writing. */
        DMAARM |= 0x01; //DMAARM0;

        /* Enable flash write. Generates a DMA trigger. Must be aligned on a 2-byte
         * boundary and is therefor implemented in assembly.
         */
       
        //write("Start Write \r");
        //halFlashStartWrite()
            FCTL |= 0x02;
           
        /* Wait for DMA transfer to complete. */
        //write("Wait for DMA transfer to complete. \r");
       
        while (!(DMAIRQ & 0x01)); //DMAIRQ_DMAIF0));

        /* Wait until flash controller not busy. */
           //write("Wait until flash controller not busy. \r");
        while (FCTL & (FCTL_BUSY ));

        /* By now, the transfer is completed, so the transfer count is reached.
         * The DMA channel 0 interrupt flag is then set, so we clear it here.
         */
        DMAIRQ &= ~DMAIRQ_DMAIF0;

        /* Read from flash to check whether the write was successful. */
        uint8 i;
        write(" read flash \r");
        for (i = 0; i < DATA_AMOUNT; i++)
        {
            writeCheck[i] = flashDataAddr[i];
           UART1_WAIT_AND_SEND(writeCheck[i]);
        }
           
            //FCTL |= 0x04; // flash cache en
       // return 0;
    }

     

    So, why the codes run ok in debugger, but NG in standalone mode? Please help.

     

  • do you know how many writing cycles can be done on the cc2530?