STM32_IAP demo.

Dependencies:   STM32_IAP mbed

Fork of IAP_internal_flash_write by Tedd OKANO

FLASH_wrtie_test EEPROM_write_test

main.cpp

Committer:
va009039
Date:
2016-04-30
Revision:
10:f3e4dd858adb
Parent:
9:ae7747b119c1

File content as of revision 10:f3e4dd858adb:

/**    IAP demo : demo code for internal Flash memory access library
 *
 *        The internal Flash memory access is described in the LPC1768 and LPC11U24 usermanual.
 *            http://www.nxp.com/documents/user_manual/UM10360.pdf
 *            http://www.nxp.com/documents/user_manual/UM10462.pdf
 *
 *               LPC1768 --
 *                    Chapter  2: "LPC17xx Memory map"
 *                    Chapter 32: "LPC17xx Flash memory interface and programming"
 *                    refering Rev. 01 - 4 January 2010
 *
 *               LPC11U24 --
 *                    Chapter  2: "LPC11Uxx Memory mapping"
 *                    Chapter 20: "LPC11Uxx Flash programming firmware"
 *                    refering Rev. 03 - 16 July 2012
 *
 *  This main.cpp demonstrates how the flash can be erased and wrote.
 *
 *  This program tries to...
 *    0. read device ID and serial#
 *    1. check if the targat sector blank
 *    2. erase the sector if it was not blank
 *    3. write into the flash (prepare before write)
 *    4. verify the data by IAP command
 *    5. show the content of the flash
 *
 *  The Flash must be erased as sectors. No overwrite can be done like SRAM.
 *  So erase should be done in size of 4K or 32K.
 *
 *  Writing sector can be done with size of 256, 512, 1024 or 4096.
 *  If other size is used, the IAP returns an error.
 *  The SRAM memory should be allocated in
 *
 *
 *        Released under the MIT License: http://mbed.org/license/mit
 *
 *        revision 1.0  09-Mar-2010   1st release
 *        revision 1.1  12-Mar-2010   chaged: to make possible to reserve flash area for user
 *                                            it can be set by USER_FLASH_AREA_START and USER_FLASH_AREA_SIZE in IAP.h
 *        revision 2.0  26-Nov.2012   LPC11U24 code added
 *        revision 2.1  26-Nov-2012   EEPROM access code imported from Suga koubou san's (http://mbed.org/users/okini3939/) library
 *                                            http://mbed.org/users/okini3939/code/M0_EEPROM_test/
 *        revision 3.0  09-Jan-2015   LPC812 and LPC824 support added
 *        revision 3.1  13-Jan-2015   LPC1114 support added
 *        revision 3.1.1 16-Jan-2015  Target MCU name changed for better compatibility across the platforms
 *        revision 3.1.2 10-Mar-2015  merged with pull requests. reinvoke_isp() added and modified read_serial() to return a pointer.
 */

#include    "mbed.h"
#include    "IAP.h"

#define     MEM_SIZE        256

#if defined(TARGET_LPC176X)
#define     TARGET_SECTOR    29     //  use sector 29 as target sector if it is on LPC1768
#elif defined(TARGET_LPC11UXX) || defined(TARGET_LPC11XX)
#define     TARGET_SECTOR    7      //  use sector  7 as target sector if it is on LPC11U24
#define     TARGET_EEPROM_ADDRESS   64
#define     TARGET_EEPROM_ADDRESS   64
#elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
#define     TARGET_SECTOR    15      //  use sector  15 as target sector if it is on LPC812

#elif defined(TARGET_NUCLEO_L152RE)||defined(TARGET_NUCLEO_F042K6)||defined(TARGET_NUCLEO_F103RB)
#define     TARGET_SECTOR    (0x7800/FLASH_PAGE_SIZE)
#define     TARGET_EEPROM_ADDRESS   (FLASH_EEPROM_BASE + 0x200)
struct {
    char* operator[](int sector) const {
        return reinterpret_cast<char*>(FLASH_BASE + sector * FLASH_PAGE_SIZE);
    }
} sector_start_adress;

#elif defined(TARGET_NUCLEO_L031K6)
#define     TARGET_SECTOR    (0x7800/FLASH_PAGE_SIZE)
#define     TARGET_EEPROM_ADDRESS   (DATA_EEPROM_BASE + 0x200)
struct {
    char* operator[](int sector) const {
        return reinterpret_cast<char*>(FLASH_BASE + sector * FLASH_PAGE_SIZE);
    }
} sector_start_adress;

#elif defined(TARGET_NUCLEO_F401RE)||defined(TARGET_NUCLEO_F411RE)||defined(TARGET_NUCLEO_F446RE)
#define     TARGET_SECTOR    3
struct {
    char* operator[](int sector) const {
        static const uint32_t offset[8] = {0x00000, 0x04000, 0x08000, 0xc000, 0x10000, 0x20000, 0x40000, 0x60000};
        return reinterpret_cast<char*>(FLASH_BASE + offset[sector]);
    }
} sector_start_adress;

#endif

void    memdump( char *p, int n );
int     isprint( int c );

IAP     iap;


int main()
{
    char    mem[ MEM_SIZE ];    //  memory, it should be aligned to word boundary
    int     *serial_number;
    int     r;

    printf( "\r\n\r\n=== IAP: Flash memory writing test ===\r\n" );
    printf( "  device-ID = 0x%08X\r\n", iap.read_ID() );

    serial_number = iap.read_serial();

    printf( "  serial# =" );
    for ( int i = 0; i < 4; i++ )
        printf( " %08X", *(serial_number + i) );
    printf( "\r\n" );

    printf( "  CPU running %dkHz\r\n", SystemCoreClock / 1000 );
    printf( "  user reserved flash area: start_address=0x%08X, size=%d bytes\r\n", iap.reserved_flash_area_start(), iap.reserved_flash_area_size() );
    printf( "  read_BootVer=0x%08X\r\r\n", iap.read_BootVer() );

    for ( int i = 0; i < MEM_SIZE; i++ )
        mem[ i ]    = i & 0xFF;

    //  blank check: The mbed will erase all flash contents after downloading new executable

    r   = iap.blank_check( TARGET_SECTOR, TARGET_SECTOR );
    printf( "blank check result = 0x%08X\r\n", r );

    //  erase sector, if required

    if ( r == SECTOR_NOT_BLANK ) {
        iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
        r   = iap.erase( TARGET_SECTOR, TARGET_SECTOR );
        printf( "erase result       = 0x%08X\r\n", r );
    }

    // copy RAM to Flash

    iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
    r   = iap.write( mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE );
    printf( "copied: SRAM(0x%08X)->Flash(0x%08X) for %d bytes. (result=0x%08X)\r\n", mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE, r );

    // compare

    r   = iap.compare( mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE );
    printf( "compare result     = \"%s\"\r\n", r ? "FAILED" : "OK" );

//#define WRITE_NEXT_BLOCK
#ifdef WRITE_NEXT_BLOCK

    // copy RAM to Flash

    iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
    r   = iap.write( mem, sector_start_adress[ TARGET_SECTOR ] + 256, MEM_SIZE );
    printf( "copied: SRAM(0x%08X)->Flash(0x%08X) for %d bytes. (result=0x%08X)\r\n", mem, sector_start_adress[ TARGET_SECTOR ], MEM_SIZE, r );

    // compare

    r   = iap.compare( mem, sector_start_adress[ TARGET_SECTOR ] + 256, MEM_SIZE );
    printf( "compare result     = \"%s\"\r\n", r ? "FAILED" : "OK" );

#endif

    printf( "showing the flash contents...\r\n" );
    memdump( sector_start_adress[ TARGET_SECTOR ], MEM_SIZE * 3 );


#if defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
    iap.prepare( TARGET_SECTOR, TARGET_SECTOR );
    r   = iap.erase_page( 241, 241 );   //  241 is page number for sector 7 with 64 byte offset

    printf( "\r\nerase page test\r\n" );
    printf( "erase page result     = \"%s\"\r\n", r ? "FAILED" : "OK" );
    printf( "showing memory dump to confirm 0x00003C40 to 0x00003C7F are erased (should be changed to 0xFF)" );

    memdump( sector_start_adress[ TARGET_SECTOR ], MEM_SIZE );
#endif


#if defined(TARGET_LPC11UXX)||defined(TARGET_STM32L1)||defined(TARGET_STM32L0) //  SAMPLE OF EEPROM ACCESS (LPC11U24 only)
    printf( "IAP: EEPROM writing test\r\n" );
    char    mem2[ MEM_SIZE ];

    r   = iap.write_eeprom( mem, (char*)TARGET_EEPROM_ADDRESS, MEM_SIZE );
    printf( "copied: SRAM(0x%08X)->EEPROM(0x%08X) for %d bytes. (result=0x%08X)\r\n", mem, TARGET_EEPROM_ADDRESS, MEM_SIZE, r );

    r   = iap.read_eeprom( (char*)TARGET_EEPROM_ADDRESS, mem2, MEM_SIZE );
    printf( "copied: EEPROM(0x%08X)->SRAM(0x%08X) for %d bytes. (result=0x%08X)\r\n", TARGET_EEPROM_ADDRESS, mem, MEM_SIZE, r );

    // compare
    r = memcmp(mem, mem2, MEM_SIZE);
    printf( "compare result     = \"%s\"\r\n", r ? "FAILED" : "OK" );

    printf( "showing the EEPROM contents...\r\n" );
    memdump( mem2, MEM_SIZE );
#endif

}


void memdump( char *base, int n )
{
    unsigned int    *p;

    printf( "  memdump from 0x%08X for %d bytes", (unsigned long)base, n );

    p   = (unsigned int *)((unsigned int)base & ~(unsigned int)0x3);

    for ( int i = 0; i < (n >> 2); i++, p++ ) {
        if ( !(i % 4) )
            printf( "\r\n  0x%08X :", (unsigned int)p );

        printf( " 0x%08X", *p );
    }

    printf( "\r\n" );
}