IAP code for Freescale platforms

Dependents:   JRO_DDSv2 18_PT1000 RDA5807M-FM-Radio flashaccess ... more

K22F

Due to the default clock setup of the K22F, flash write access is there disabled. In the future I might add a workaround, but for now see: https://developer.mbed.org/questions/52738/Error-with-FreescaleIAP-code-with-K22F/

Be careful with which flash you are erasing/overwriting!

Example code:

#include "mbed.h"
#include "FreescaleIAP.h"


int main() {
    int address = flash_size() - SECTOR_SIZE;           //Write in last sector
    
    int *data = (int*)address;
    printf("Starting\r\n"); 
    erase_sector(address);
    int numbers[10] = {0, 1, 10, 100, 1000, 10000, 1000000, 10000000, 100000000, 1000000000};
    program_flash(address, (char*)&numbers, 40);        //10 integers of 4 bytes each: 40 bytes length
    printf("Resulting flash: \r\n");
    for (int i = 0; i<10; i++)
        printf("%d\r\n", data[i]);
    
    printf("Done\r\n\n");
        

    while (true) {
    }
}

For an example on using this for a bootloader, check out: http://developer.mbed.org/users/Sissors/code/Bootloader_K64F/

If you want to permanently store a variable between resets, you can run into the problem of how to define the value the first time. Since the mbed drag-and-drop loader seems to issue a full-chip erase, you cannot first upload a program to set the initial value, and then switch to the regular program: The full-chip erase will also erase your initial value. One option is to use the same statements as used in the bootloader example to force it to program initial values for your variables on your memory address. This should work fine, however it is target dependent where you want to program it (generally your last sector), so it makes for a less nice example program. You can also try to detect if it is the initial run by looking at the state of the flash, by default this is all '1's. The following example does this:

#include "mbed.h"
#include "FreescaleIAP.h"

int main() {    
    
    int address = flash_size() - SECTOR_SIZE;           //Write in last sector
    int *data = (int*)address;
    
    //By default flash is initialized at 0xFF, this is signed -1, so now we know
    //the program runs for the first time. You of course need to make sure your program
    //never writes -1 to this variable if you use this method
    
    //Alternatively you could also do the same, but with a seperate "initial run" variable added,
    //so your other variables can take any value
    if (data[0] == -1) {
        printf("Initial run\r\n");
        printf("Writing 42 and 42\r\n");
        erase_sector(address);
        int newvalues[2] = {42, 42};
        program_flash(address,(char*) newvalues, 8);     //Two integers of 4 bytes = 8 bytes
        while(1);
    }
    printf("Current = %d and %d, new is %d and %d\r\n", data[0], data[1], data[0]+1, data[1]-1);
    int newvalues[2] = {data[0]+1, data[1]-1};
    erase_sector(address);
    program_flash(address, (char*) newvalues, 8);
    while(1);
}
Committer:
Sissors
Date:
Wed Mar 16 20:20:17 2016 +0000
Revision:
11:ab8a833a25eb
Parent:
8:6749f7702fa5
Disabled debug

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 0:8eef5a3e83ca 1 #ifndef FREESCALEIAP_H
Sissors 0:8eef5a3e83ca 2 #define FREESCALEIAP_H
Sissors 0:8eef5a3e83ca 3
Sissors 7:474d231b2f35 4 #ifdef TARGET_Freescale
Sissors 7:474d231b2f35 5
Sissors 0:8eef5a3e83ca 6 #include "mbed.h"
Sissors 0:8eef5a3e83ca 7
Sissors 5:a5cfedcf55d6 8 #if defined(TARGET_KLXX)
Sissors 2:70ade1638644 9 #define SECTOR_SIZE 1024
Sissors 8:6749f7702fa5 10 #elif defined(TARGET_K20D5M) | (TARGET_K22F) | (TARGET_TEENSY3_1)
Sissors 2:70ade1638644 11 #define SECTOR_SIZE 2048
Sissors 5:a5cfedcf55d6 12 #elif defined(TARGET_K64F)
Sissors 2:70ade1638644 13 #define SECTOR_SIZE 4096
Sissors 2:70ade1638644 14 #else
Sissors 5:a5cfedcf55d6 15 #warning FreescaleIAP unknown target, using default 1024B
Sissors 2:70ade1638644 16 #define SECTOR_SIZE 1024
Sissors 2:70ade1638644 17 #endif
Sissors 0:8eef5a3e83ca 18
Sissors 0:8eef5a3e83ca 19 enum IAPCode {
Sissors 0:8eef5a3e83ca 20 BoundaryError = -99, //Commands may not span several sectors
Sissors 0:8eef5a3e83ca 21 AlignError, //Data must be aligned on longword (two LSBs zero)
Sissors 0:8eef5a3e83ca 22 ProtectionError, //Flash sector is protected
Sissors 0:8eef5a3e83ca 23 AccessError, //Something went wrong
Sissors 0:8eef5a3e83ca 24 CollisionError, //During writing something tried to flash which was written to
Sissors 0:8eef5a3e83ca 25 LengthError, //The length must be multiples of 4
Sissors 1:702fd2d53c17 26 RuntimeError,
Sissors 1:702fd2d53c17 27 EraseError, //The flash was not erased before writing to it
Sissors 0:8eef5a3e83ca 28 Success = 0
Sissors 0:8eef5a3e83ca 29 };
Sissors 0:8eef5a3e83ca 30
Sissors 2:70ade1638644 31 /** Erase a flash sector
Sissors 2:70ade1638644 32 *
Sissors 2:70ade1638644 33 * The size erased depends on the used device
Sissors 2:70ade1638644 34 *
Sissors 2:70ade1638644 35 * @param address address in the sector which needs to be erased
Sissors 2:70ade1638644 36 * @param return Success if no errors were encountered, otherwise one of the error states
Sissors 2:70ade1638644 37 */
Sissors 0:8eef5a3e83ca 38 IAPCode erase_sector(int address);
Sissors 2:70ade1638644 39
Sissors 2:70ade1638644 40 /** Program flash
Sissors 2:70ade1638644 41 *
Sissors 2:70ade1638644 42 * Before programming the used area needs to be erased. The erase state is checked
Sissors 2:70ade1638644 43 * before programming, and will return an error if not erased.
Sissors 2:70ade1638644 44 *
Sissors 2:70ade1638644 45 * @param address starting address where the data needs to be programmed (must be longword alligned: two LSBs must be zero)
Sissors 2:70ade1638644 46 * @param data pointer to array with the data to program
nyatla 6:186db0d96fcf 47 * @param length number of bytes to program (must be a multiple of 4. must be a multiple of 8 when K64F)
Sissors 2:70ade1638644 48 * @param return Success if no errors were encountered, otherwise one of the error states
Sissors 2:70ade1638644 49 */
Sissors 1:702fd2d53c17 50 IAPCode program_flash(int address, char *data, unsigned int length);
Sissors 0:8eef5a3e83ca 51
Sissors 2:70ade1638644 52 /**
Sissors 2:70ade1638644 53 * Returns size of flash memory
Sissors 2:70ade1638644 54 *
Sissors 2:70ade1638644 55 * This is the first address which is not flash
Sissors 2:70ade1638644 56 *
Sissors 2:70ade1638644 57 * @param return length of flash memory in bytes
Sissors 2:70ade1638644 58 */
Sissors 2:70ade1638644 59 uint32_t flash_size(void);
Sissors 2:70ade1638644 60
Sissors 7:474d231b2f35 61 #endif
Sissors 0:8eef5a3e83ca 62 #endif