EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

LPC2148: How to write number of 100 byes of data in flash sector

Started by Wool Gather October 8, 2010
Hi every one,

I am new with this ARM7 uC.
I have been gone through Datasheet of LPC2148 for writing data in to flash.
I have couple of question about how to write / re- write data on sectors.

Example: If i would like to write 100 byte of data to sector number 8, the size
of sector 8 is 32 KByte.
I am getting data from UART 0 after every five minutes and storing that data in
to global buffer variable.

So every five minutes i am getting 100 bytes of data and i have to store that
all data in to the same sector number, when flash sector number 8 is full with
data, i have to send that all data to UART 1.

My main concern here is how i can write 100 byte of data to flash sector number
8 only.
Please can any one help me about any algorithm or any example which will explain
me to about writing algorithm in to flash.

Thanks in advance.

Kind Regards,
Wool

An Engineer's Guide to the LPC2100 Series

Hi

Please see: http://www.utasker.com/forum/index.php?topic6.0

regards

Mark
--- In l..., Wool Gather wrote:
>
> Hi every one,
>
> I am new with this ARM7 uC.
> I have been gone through Datasheet of LPC2148 for writing data in to flash.
> I have couple of question about how to write / re- write data on sectors.
>
> Example: If i would like to write 100 byte of data to sector number 8, the size
> of sector 8 is 32 KByte.
> I am getting data from UART 0 after every five minutes and storing that data in
> to global buffer variable.
>
> So every five minutes i am getting 100 bytes of data and i have to store that
> all data in to the same sector number, when flash sector number 8 is full with
> data, i have to send that all data to UART 1.
>
> My main concern here is how i can write 100 byte of data to flash sector number
> 8 only.
> Please can any one help me about any algorithm or any example which will explain
> me to about writing algorithm in to flash.
>
> Thanks in advance.
>
> Kind Regards,
> Wool
>

Hi Mark

I read this documents which you mentationed and did understand how i can write
in to flash.
After this i got one demo program to write in to flash and where it is possible
for me to write 512 byte of data.
But when i will try to write in chunk of 256 byte of data i am not able to
write. Could you please have look this code.
Please help me about this, where i am wrong in this code for writing 256 byte of
data.
I am using keil as a compiler.

#include "lpc214x.h"
// Clock Frequency
#define XTAL    12000000                   // Oscillator Frequency
#ifdef BYPASS_PLL
#define CPUCLK  XTAL                       // CPU Clock without PLL
#else
#define CPUCLK (XTAL*5)                    // CPU Clock with PLL
#endif
#define CCLK   (CPUCLK / 1000)             // CPU Clock in kHz

// Phase Locked Loop (PLL) definitions
#define PLL_BASE        0xE01FC080         // PLL Base Address
#define PLLCON_OFS      0x00               // PLL Control Offset
#define PLLSTAT_OFS     0x08               // PLL Status Offset
#define PLLFEED_OFS     0x0C               // PLL Feed Offset
#define PLLCON_PLLE     0x01               // PLL Enable
#define PLLCON_PLLD     0x00               // PLL Disable
#define PLLCON_PLLC     0x03               // PLL Connect
#define PLLSTAT_PLOCK   0x0400             // PLL Lock Status

struct iap_in {
  unsigned int cmd;
  unsigned int par[4];
};
typedef void (*IAP)(struct iap_in *in, unsigned int *result);
#define iap_entry ((IAP) 0x7FFFFFF1)       // IAP Entry Point

/* Default Interrupt Function: may be called when interrupts are disabled */
void def_isr (void) __irq  {
 ;
}

#ifdef BYPASS_PLL
/*
 * PLL Feed Sequence
 */
void feed_pll (void) {
  unsigned int adr, r1, r2;
  adr = PLL_BASE;
  __asm {
    MOV     r1, #0xAA
    MOV     r2, #0x55
    STR     r1, [adr, #PLLFEED_OFS]
    STR     r2, [adr, #PLLFEED_OFS]
  }
}
/*
 * Switch CPU to PLL clock
 */
void start_pll (void) {
  PLLCON = PLLCON_PLLE;
  feed_pll();
  while ((PLLSTAT & PLLSTAT_PLOCK) == 0);
  PLLCON = PLLCON_PLLC;
  feed_pll();
}
/*
 * Switch CPU to standard XTAL
 */
void stop_pll(void) {
  PLLCON = PLLCON_PLLD;
  feed_pll();
}
#endif

//Convert 'addr' to Sector Number
unsigned int get_secnum (unsigned int addr) {
  unsigned int n;
  n = ((unsigned int) addr >> 13) & 0x1F;  // Pseudo Sector Number
  if (n >= (0x30000 >> 13))  {
    n -= 14;                               // High Small 8kB Sectors
  }
  else if (n >= (0x10000 >> 13))  {
    n  = 7 + (n >> 3);                     // Large 64kB Sectors
  }
  return (n);                              // Sector Number
}

//Erase Sector between 'start' and 'end'
//Return: IAP Error Code (0 when OK)
unsigned int erase (unsigned int start, unsigned int end) {
  struct iap_in iap;                       // IAP Input Parameters
  unsigned int  result[16];                // IAP Results
  unsigned int  save_VicInt;               // for saving VICIntEnable
  save_VicInt = VIC_IntEnable;              // Save Interrupt Enable Status
  VIC_IntEnClr = 0xFFFFFFFF;                // Disable all Interrupts
#ifdef BYPASS_PLL
  stop_pll();                              // IAP requires to run without PLL
#endif
  iap.cmd = 50;                            // IAP Command: Prepare Sectors for
Write
  iap.par[0] = get_secnum (start);         // Start Sector
  iap.par[1] = get_secnum (end);           // End Sector
  iap_entry (&iap, result);                // Call IAP Function
  if (result[0]) goto exit;                // Error occured?
  iap.cmd = 52;                            // IAP Command: Erase Flash
  iap.par[0] = get_secnum (start);         // Start Sector
  iap.par[1] = get_secnum (end);           // End Sector
  iap.par[2] = CCLK;                       // CPU Clock
  iap_entry (&iap, result);                // Call IAP Function
exit:
#ifdef BYPASS_PLL
  start_pll();                             // Start PLL
#endif
  VIC_IntEnable = save_VicInt;              // Restore Interrupt Enable Status
  return (result[0]);
}

/*
  Program *data to addr, number of bytes specified by size
  Return: IAP Error Code (0 when OK)
  NOTES:  size should be 512, 1024, 4096 or 8192
 */
unsigned int program (unsigned int addr, unsigned char *data, unsigned int size)
{
  struct iap_in iap;                       // IAP Input Parameters
  unsigned int  result[16];                // IAP Results
  unsigned int  save_VicInt;               // for saving VICIntEnable
  save_VicInt = VIC_IntEnable;              // Save Interrupt Enable Status
  VIC_IntEnClr = 0xFFFFFFFF;                // Disable all Interrupts
#ifdef BYPASS_PLL
  stop_pll();                              // IAP requires to run without PLL
#endif
  iap.cmd = 50;                            // IAP Command: Prepare Sectors for
Write
  iap.par[0] = get_secnum (addr);         // Start Sector
  iap.par[1] = iap.par[0];                 // End Sector
  iap_entry (&iap, result);                // Call IAP Function
  if (result[0]) goto exit;                // Error occured?
  iap.cmd = 51;                            // IAP Command: Copy RAM to Flash
  iap.par[0] = addr;                       // Destination Address
  iap.par[1] = (unsigned int) data;        // Source Address
  iap.par[2] = size;                       // Number of Bytes
  iap.par[3] = CCLK;                       // CPU Clock
  iap_entry (&iap, result);                // Call IAP Function
exit:
#ifdef BYPASS_PLL
  start_pll();                             // Start PLL
#endif
  VIC_IntEnable = save_VicInt;              // Restore Interrupt Enable Status
  return (result[0]);
}

unsigned char vals[255];

void main (void)  {
  unsigned int i;
  unsigned int volatile start;
  for (start = 0; start < 1000000; start++) {
    ;  // wait for debugger connection (about 0.3 sec)
  }
  VIC_DefVectAddr = (unsigned int) def_isr; // for Spurious Interrupts
  for (i = 0; i < sizeof (vals); i++)  {
    vals[i] = (unsigned char) i;
  }
  i = erase   (0x10000, 0x17FFF);
  i = program (0x10000, vals, 256);
  i = program (0x11000, vals, 256);
  i = program (0x12000, vals, 256);
  i = erase   (0x10000, 0x31FFF);
  i = erase   (0x12000, 0x33FFF);
  while (1);
}

Thanks in advance.

Kind regards,
Vishal

________________________________
From: Mark
To: l...
Sent: Fri, October 8, 2010 6:49:46 PM
Subject: [lpc2000] Re: LPC2148: How to write number of 100 byes of data in flash
sector

 
Hi

Please see: http://www.utasker.com/forum/index.php?topic6.0

regards

Mark

--- In l..., Wool Gather wrote:
>
> Hi every one,
>
> I am new with this ARM7 uC.
> I have been gone through Datasheet of LPC2148 for writing data in to flash.
> I have couple of question about how to write / re- write data on sectors.
>
> Example: If i would like to write 100 byte of data to sector number 8, the size
>
> of sector 8 is 32 KByte.
> I am getting data from UART 0 after every five minutes and storing that data in
>
> to global buffer variable.
>
> So every five minutes i am getting 100 bytes of data and i have to store that
> all data in to the same sector number, when flash sector number 8 is full with

> data, i have to send that all data to UART 1.
>
> My main concern here is how i can write 100 byte of data to flash sector number
>
> 8 only.
> Please can any one help me about any algorithm or any example which will
>explain
>
> me to about writing algorithm in to flash.
>
> Thanks in advance.
>
> Kind Regards,
> Wool
>

The 2024 Embedded Online Conference