I am having trouble passing arguments to a function that has been copied to RAM and once I have a buffer full of data, I pass a pointer to the buffer along with a Flash memory address, and then the number of bytes I want programmed. The example code I have found works well; however, the example code uses fixed values for the buffer and address locations. What I am seeing in my debugger is the pointers are pointing to the CPU registers instead of pointing to the address variables I am passing to the function. I suspect when I copy the write function to RAM, this gets the pointers all out of WHACK, but I am stumped how to solve this without diving into an assembly program to solve this.(not sure this would work wither). I have attached my compiled code.
FYI, once the buffer is 512 bytes, I call the write routine using this
if ( !write_block_int ( &writeBuffer[0], intCurrentSegment, data_buff_index) ) { break;}
I am using an MSP430F2410; IAR EW 5.40
/*****************************************************************************
* Filename: flashblockwrite.c
*
*
* Description: Module used to perform the flash block write.
*
* Dependencies:
*
* Modifications:
* Date Programmer Description
* -------- -------------- -----------------------------------------------
*
*****************************************************************************/
msp430f2410.h"
#include "string.h" // included for memcpy function call
#pragma segment="FLASHCODE" // Define flash segment code
#pragma segment="RAMCODE"
// array of received data
extern unsigned char writeBuffer[] ;
// writeBuffer array index pointer (and, when full, number of bytes to write to FLASH)
extern unsigned int data_buff_index ;
// holds the address of the start of the segment for use during flash write
extern unsigned int intCurrentSegment ;
/******************************************************************************
* Function Name: copy_flash_to_RAM
*
*
* Parameter: none
* Input: none
* Returns: none
*
* Description:
* This function copies the function FLASH using Block Write
*
* Change log:
* Date Author Description
*
*
******************************************************************************/
void copy_flash_to_RAM (void)
{
unsigned int *flash_start_ptr; // Initialize pointers
unsigned int *flash_end_ptr;
unsigned int *RAM_start_ptr;
//Initialize flash and ram start and end address
flash_start_ptr = (unsigned int *)__segment_begin("FLASHCODE");
flash_end_ptr = (unsigned int *)__segment_end("FLASHCODE");
RAM_start_ptr = (unsigned int *)__segment_begin("RAMCODE");
//calculate function size
unsigned long function_size = (unsigned long)(flash_end_ptr) - (unsigned long)(flash_start_ptr);
// Copy flash function to RAM
memcpy(RAM_start_ptr,flash_start_ptr,function_size);
}
/******************************************************************************
* Function: write_block_int()
*
*
* Purpose: This function is responsible for writing the contents
* of commBuffer[] to FLASH; however, this will be done from RAM.
* This function is copied into RAM first before writing to FLASH
* This portion of the code is first stored in Flash and then copied
* to RAM during initialization. Ultimately, this function executes
* from RAM.
*
* Modifications:
* Date Name Description
* ------ ----- -----------------------------------------------------
*
*
******************************************************************************/
#pragma location="RAMCODE"
unsigned char write_block_int( unsigned char *ptrSource, unsigned int *ptrDest, unsigned int length )
// BOOL write_block_int(void)
{
//Inputs:
// used for counting the number of bytes being written to FLASH
unsigned int i, u, dex;
unsigned int numBytesToWrite, numBlocksToWrite, modBytesToWrite;
// Keep local copy of initial parameters to use with memcmp
void *Source = ptrSource;
void *p_destination = ptrDest;
size_t bytes = length;
unsigned int* Flashptr;
Flashptr = (unsigned int*)ptrDest; // Initialize write address
//flashptr = &intCurrentSegment;
__disable_interrupt(); // 5xx Workaround: Disable global
// interrupt while erasing.
// Erase Flash
while(BUSY & FCTL3); // Check if Flash being used
FCTL3 = FWKEY; // Clear Lock bit
FCTL1 = FWKEY+ERASE; // Set Erase bit
*(unsigned char *)Flashptr = 0; // Dummy write to erase Flash seg
while(BUSY & FCTL3); // Check if Erase is done
// get number of bytes from writeBuffer[] to write. Total can be < 512.
// FLASH block write only writes 64 blocks at a time. The BLKWRT bit must
// be cleared after the current block has completed its write process.
// Then set the BLKWRT bit again to write the next block.
// get number of blocks to write to segment
// and any remaining bytes if writeBuffer[] is not a full 512 bytes.
numBlocksToWrite = data_buff_index / 64;
modBytesToWrite = data_buff_index % 64;
if ( numBlocksToWrite == 0 )
{
numBytesToWrite = data_buff_index;
} // end if (numBlocksToWrite == 0)
else
{
numBytesToWrite = 64;
}// end else
// Write Flash
FCTL1 = FWKEY+BLKWRT+WRT; // Enable block write
for (u = 0; u < numBlocksToWrite; u++)
{
for(i = 0; i < numBytesToWrite; i++)
{
*Flashptr++ = ptrSource[dex++]; // Write contents of writeBuffer[] to Flash
while(!(WAIT & FCTL3)); // Test wait until ready for next byte
}
// on the last block of the current segment check if that block is
// a full 64 bytes. If not, change the number of bytes to write
if (numBlocksToWrite < 8 || ( numBlocksToWrite - u ) == 1)
{
numBytesToWrite = modBytesToWrite;
} // end if (numBlocksToWrite)
FCTL1 = FWKEY; // Clear WRT, BLKWRT
while(BUSY & FCTL3); // Check for write completion
FCTL3 = FWKEY+LOCK; // Set LOCK
} // end for u
// verify buffer is same as segment written
return ( memcmp ( Source, p_destination, bytes ) == 0 ? 1 : 0 );
}