DipCortex EEprom IAP library

Dependents:   DipCortex-USB-EEProm vfd_modular_clock_mbed

DipCortex EEprom library.

Example project :

Import programDipCortex-USB-EEProm

DipCortex USB CDC + EEprom

DipCortex-EEprom.cpp

Committer:
SolderSplashLabs
Date:
2014-02-23
Revision:
0:53297f36733d

File content as of revision 0:53297f36733d:

//-----------------------------------------------------------------------------
//* Software that is described herein is for illustrative purposes only
//* which provides customers with programming information regarding the
//* products. This software is supplied "AS IS" without any warranties.
//* NXP Semiconductors assumes no responsibility or liability for the
//* use of the software, conveys no license or title under any patent,
//* copyright, or mask work right to the product. NXP Semiconductors
//* reserves the right to make changes in the software without
//* notification. NXP Semiconductors also make no representation or
//* warranty that such application will be suitable for the specified
//* use without further testing or modification.
//* Permission to use, copy, modify, and distribute this software and its
//* documentation is hereby granted, under NXP Semiconductors'
//* relevant copyright in the software, without fee, provided that it
//* is used in conjunction with NXP Semiconductors microcontrollers.  This
//* copyright, permission, and disclaimer notice must appear in all copies of
//* this code.
//-----------------------------------------------------------------------------

#include <stdint.h>
#include <string.h>
#include "DipCortex-EEprom.h"
#include "LPC13Uxx.h"            

unsigned param_table[5];
unsigned result_table[5];

unsigned cclk;
char flash_buf[FLASH_BUF_SIZE];
unsigned * flash_address;
unsigned byte_ctr;

#define iap_entry ((void (*)(unsigned [],unsigned []))(IAP_ADDRESS))

void IAP_WriteData(unsigned cclk,unsigned flash_address,unsigned * flash_data_buf, unsigned count);
void IAP_PrepareEraseSector( unsigned flash_address );
void IAP_EraseSector(unsigned start_sector,unsigned end_sector,unsigned cclk);
void IAP_PrepareSector(unsigned start_sector,unsigned end_sector,unsigned cclk);


void IAP_WriteData(unsigned cclk,unsigned flash_address,unsigned * flash_data_buf, unsigned count)
{
    param_table[0] = COPY_RAM_TO_FLASH;
    param_table[1] = flash_address;
    param_table[2] = (unsigned)flash_data_buf;
    param_table[3] = count;
    param_table[4] = cclk;
    iap_entry(param_table,result_table);
}

void IAP_EraseSector(unsigned start_sector,unsigned end_sector,unsigned cclk)
{
    param_table[0] = ERASE_SECTOR;
    param_table[1] = start_sector;
    param_table[2] = end_sector;
    param_table[3] = cclk;
    iap_entry(param_table,result_table);
}

void IAP_PrepareSector(unsigned start_sector,unsigned end_sector,unsigned cclk)
{
    param_table[0] = PREPARE_SECTOR_FOR_WRITE;
    param_table[1] = start_sector;
    param_table[2] = end_sector;
    param_table[3] = cclk;
    iap_entry(param_table,result_table);
}

int IAP_ErasePage ( unsigned startPageNo, unsigned endPageNo, unsigned cclk )
{
    param_table[0] = ERASE_PAGE;
    param_table[1] = startPageNo;
    param_table[2] = endPageNo;
    param_table[3] = cclk;
    iap_entry(param_table,result_table);

    if( result_table[0] == CMD_SUCCESS )
    {
        return (1);
    }
    else
    {
        return (0);
    }
}

void IAP_PrepareEraseSector( unsigned flash_address )
{
unsigned i;
unsigned end_sector;

    end_sector = MAX_USER_SECTOR;

    for(i=0; i<=end_sector; i++)
    {
        if(flash_address < (SECTOR_0_START_ADDR + ((i + 1) * SECTOR_SIZE)))
        {
            LPC_GPIO->NOT[ 1 ] = 1<<16;

            // if its the start of a sector, erase it
            if( flash_address == SECTOR_0_START_ADDR + (SECTOR_SIZE * i))
            {
                IAP_PrepareSector(i,i,cclk);
                IAP_EraseSector(i,i,cclk);
            }
            IAP_PrepareSector(i,i,cclk);
            break;
        }
    }
}

int IAP_WritePage (unsigned * dst, char * src, unsigned no_of_bytes)
{
unsigned enabled_irqs;

    // A copy of any enabled interrupts
    enabled_irqs = NVIC->ISER[0];
    NVIC->ICER[0] = enabled_irqs;

    memcpy(&flash_buf[0], src, no_of_bytes);

    // If the address is the start of a sector then, prepare and erase it
    IAP_PrepareEraseSector((unsigned)dst);
    //IAP_ErasePage (1, 1, cclk);

    IAP_WriteData(cclk, (unsigned)dst, (unsigned *)flash_buf, FLASH_BUF_SIZE);

    NVIC->ISER[0] = enabled_irqs;

    return( result_table[0] );
}

int IAP_CheckForUserCode(void)
{
    unsigned *pmem, checksum,i;

    param_table[0] = BLANK_CHECK_SECTOR;
    param_table[1] = USER_START_SECTOR;
    param_table[2] = USER_START_SECTOR;
    iap_entry(param_table,result_table);

    if( result_table[0] == CMD_SUCCESS )
    {
        // it's blank
        return (0);
    }
    else
    {
        /*
         * The reserved Cortex-M3 exception vector location 7 (offset 0x001C
         * in the vector table) should contain the 2’s complement of the
         * checksum of table entries 0 through 6. This causes the checksum
         * of the first 8 table entries to be 0. This code checksums the
         * first 8 locations of the start of user flash. If the result is 0,
         * then the contents is deemed a 'valid' image.
         */
        checksum = 0;
        pmem = (unsigned *)USER_START_SECTOR;
        for (i = 0; i <= 7; i++)
        {
            checksum += *pmem;
            pmem++;
        }
        if (checksum != 0)
        {
            // Failed to checksum, not valid
        }
        else
        {
            // Checksum passed
            return (1);
        }
    }

    return (0);
}

void IAP_Init( void )
{
    cclk = CCLK;
    byte_ctr = 0;
    flash_address = (unsigned *)UPDATE_REQD;
}

void IAP_Eeprom_Write ( uint32_t eeAddress, uint8_t* buffAddress, uint32_t byteCount )
{
    unsigned int command[5], result[4];

    command[0] = EEPROM_WRITE;
    command[1] = (uint32_t) eeAddress;
    command[2] = (uint32_t) buffAddress;
    command[3] = byteCount;
    command[4] = cclk;

    /* Invoke IAP call...*/
    iap_entry(command, result);
}

void IAP_Eeprom_Read ( uint32_t eeAddress, uint8_t* buffAddress, uint32_t byteCount )
{
    unsigned int command[5], result[4];

    command[0] = EEPROM_READ;
    command[1] = (uint32_t) eeAddress;
    command[2] = (uint32_t) buffAddress;
    command[3] = byteCount;
    command[4] = cclk;

    /* Invoke IAP call...*/
    iap_entry( command, result);
}