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
Revision 0:53297f36733d, committed 2014-02-23
- Comitter:
- SolderSplashLabs
- Date:
- Sun Feb 23 22:52:19 2014 +0000
- Commit message:
- DipCortex EEprom, port of the NXP IAP code that allows reading and writing to the on chip 4KB eeprom.
Changed in this revision
DipCortex-EEprom.cpp | Show annotated file Show diff for this revision Revisions of this file |
DipCortex-EEprom.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DipCortex-EEprom.cpp Sun Feb 23 22:52:19 2014 +0000 @@ -0,0 +1,211 @@ +//----------------------------------------------------------------------------- +//* 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); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DipCortex-EEprom.h Sun Feb 23 22:52:19 2014 +0000 @@ -0,0 +1,83 @@ +#define USER_START_SECTOR SECTOR_2_START + +#ifndef _SBL_IAP_H +#define _SBL_IAP_H + + +#define SECTOR_0_START 0x00000000 +#define SECTOR_1_START 0x00001000 +#define SECTOR_2_START 0x00002000 +#define SECTOR_3_START 0x00003000 +#define SECTOR_4_START 0x00004000 +#define SECTOR_5_START 0x00005000 +#define SECTOR_6_START 0x00006000 +#define SECTOR_7_START 0x00007000 +#define SECTOR_8_START 0x00008000 +#define SECTOR_9_START 0x00009000 +#define SECTOR_10_START 0x0000A000 +#define SECTOR_11_START 0x0000B000 +#define SECTOR_12_START 0x0000C000 +#define SECTOR_13_START 0x0000D000 +#define SECTOR_14_START 0x0000E000 +#define SECTOR_15_START 0x0000F000 + + +#define SECTOR_0_END 0x00000FFF +#define SECTOR_1_END 0x00001FFF +#define SECTOR_2_END 0x00002FFF +#define SECTOR_3_END 0x00003FFF +#define SECTOR_4_END 0x00004FFF +#define SECTOR_5_END 0x00005FFF +#define SECTOR_6_END 0x00006FFF +#define SECTOR_7_END 0x00007FFF +#define SECTOR_8_END 0x00008FFF +#define SECTOR_9_END 0x00009FFF +#define SECTOR_10_END 0x0000AFFF +#define SECTOR_11_END 0x0000BFFF +#define SECTOR_12_END 0x0000CFFF +#define SECTOR_13_END 0x0000DFFF +#define SECTOR_14_END 0x0000EFFF +#define SECTOR_15_END 0x0000FFFF + +#define CCLK 72000 /* 72,000 KHz for IAP call WiFI Dip and M3 - TODO : Addjust for M0*/ + +#define FLASH_BUF_SIZE 256 +#define SECTOR_0_START_ADDR 0 +#define SECTOR_SIZE 4096 +#define MAX_USER_SECTOR 16 +#define PAGES_PER_SECTOR 16 + +//extern const unsigned sector_start_map[]; +//extern const unsigned sector_end_map[]; +extern const unsigned crp; + +unsigned write_flash(unsigned * dst, char * src, unsigned no_of_bytes); +void erase_user_flash(void); +void IAP_Init(void); +int IAP_CheckForUserCode(void); +int IAP_WritePage (unsigned * dst, char * src, unsigned no_of_bytes); +void IAP_Eeprom_Write ( uint32_t eeAddress, uint8_t* buffAddress, uint32_t byteCount ); +void IAP_Eeprom_Read ( uint32_t eeAddress, uint8_t* buffAddress, uint32_t byteCount ); + +typedef enum +{ +PREPARE_SECTOR_FOR_WRITE=50, +COPY_RAM_TO_FLASH=51, +ERASE_SECTOR=52, +BLANK_CHECK_SECTOR=53, +READ_PART_ID=54, +READ_BOOT_VER=55, +COMPARE=56, +REINVOKE_ISP=57, +ERASE_PAGE=59, +EEPROM_WRITE=61, +EEPROM_READ=62, + +}IAP_Command_Code; + +#define CMD_SUCCESS 0 +#define IAP_ADDRESS 0x1FFF1FF1 + +#define UPDATE_REQD 133 + +#endif /* _SBL_IAP_H */