Hey Mark,
here is "my" code :smileywink: I think it's almost the same like yours. But when I try to work with the ERASE_ALL_BLOCKS command
the CW shows me a strange erros message "no source found at ...0xFFFFFF....." and after that the device is secured. So I have to reflash it and work without the
ERASE_ALL_BLOCKS command. Then the code works very well.
Please notice that I set: FTFL_FSTAT |= FTFL_FSTAT_CCIF_MASK;
Behind the Partition command and the flex ram command. Without this, there is no partitioning...
I did that because the data sheet says: After clearing CCIF to launch the Program Section command,...
But this sentence is written behind every command sentence. I'm not sure why I can't find this in your code
behind the PROGRAM_LONG_WORD command...
However, behind the ERASE_ALL_BLOCKS command the CCIF Flag hasn't got an effect.
* FLASH.c
#include "FLASH.h"
// This routine runs from SRAM - the reason why the pointer is passed is to avoid the routine taking it from a const value in FLASH, which is then not code location dependent
static unsigned short fnFlashRoutine[] = // to avoid potential compiler in-lining of the routine (removing position independency) the machine code is used directly
{
0x2180, // MOVS r1,#0x80 load the value 0x80 (command complete interrupt flag) to register r1
0x7001, // STRB r1,[r0,#0x00] write r1 (0x80) to the passed pointer location (r0)
0x7801, // LDRB r1,[r0,#0x00] read back from the same location to r1
0x0609, // LSLS r1,r1,#24 shift the register content by 24 bits to the left so that the command complete interrupt flag is at bit 31
0xd5fc, // BPL -4 if the command complete interrupt flag bit is '0' (register content is not negative value) branch back to read its value again
0x4770 // BX lr return from sub-routine
};
void FLASH(unsigned char ucCommand, unsigned long *ptrWord, unsigned long *ptr_ulWord)
{
static void (*fnRAM_code)(volatile unsigned char *) = 0;
if (!fnRAM_code) // the first time this is used it will load the program to SRAM
{
#define PROG_WORD_SIZE 30 // adequate space for the small program
int i = 0;
unsigned char *ptrThumb2 = (unsigned char *)fnFlashRoutine;
static unsigned short usProgSpace[PROG_WORD_SIZE]; // make space for the routine on stack (this will have an even boundary)
ptrThumb2 = (unsigned char *)(((uint32_t)ptrThumb2) & ~0x1); // thumb 2 address
while (i < PROG_WORD_SIZE) // copy program to SRAM
{
usProgSpace[i++] = *(unsigned short *)ptrThumb2;
ptrThumb2 += sizeof (unsigned short);
}
ptrThumb2 = (unsigned char *)usProgSpace;
ptrThumb2++; // create a thumb 2 call
fnRAM_code = (void(*)(volatile unsigned char *))(ptrThumb2);
}
while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF_MASK)) {} // wait for previous commands to complete
if (FTFL_FSTAT & (FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_FPVIOL_MASK)) // check for errors in previous command
{
FTFL_FSTAT = (FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_FPVIOL_MASK); // clear old errors
}
switch (FTFL_FCCOB0 = ucCommand) // enter the command sequence
{
case FCMD_ERASE_ALL_BLOCKS:
break;
case FCMD_PROGRAM_PARTITION:
FTFL_FCCOB4 = (unsigned char)((uint32_t)0x34);
FTFL_FCCOB5 = (unsigned char)((uint32_t)0x02);
FTFL_FSTAT |= FTFL_FSTAT_CCIF_MASK;
break;
case FCMD_SET_FLEXRAM_FUNCTION:
FTFL_FCCOB1 = (unsigned char)((uint32_t)0x00);
FTFL_FSTAT |= FTFL_FSTAT_CCIF_MASK;
break;
case FCMD_ERASE_FLASH_SECTOR:
FTFL_FCCOB1 = (unsigned char)(((uint32_t)ptrWord) >> 16); // set address in flash
FTFL_FCCOB2 = (unsigned char)(((uint32_t)ptrWord) >> 8);
FTFL_FCCOB3 = (unsigned char)((uint32_t)ptrWord);
break;
case FCMD_PROGRAM_LONG_WORD:
FTFL_FCCOB1 = (unsigned char)(((uint32_t)ptrWord) >> 16); // set address in flash
FTFL_FCCOB2 = (unsigned char)(((uint32_t)ptrWord) >> 8);
FTFL_FCCOB3 = (unsigned char)((uint32_t)ptrWord);
FTFL_FCCOB4 = (unsigned char)(*ptr_ulWord >> 24); // enter the long word to be programmed
FTFL_FCCOB5 = (unsigned char)(*ptr_ulWord >> 16);
FTFL_FCCOB6 = (unsigned char)(*ptr_ulWord >> 8);
FTFL_FCCOB7 = (unsigned char)(*ptr_ulWord);
break;
}
DisableInterrupts; // protect this region from interrupts
fnRAM_code((volatile unsigned char *)FTFL_BLOCK); // execute the command from SRAM
EnableInterrupts; // safe to accept interrupts again
if(FTFL_FSTAT & (FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_FPVIOL_MASK | FTFL_FSTAT_MGSTAT0_MASK))
{
error_struct.general_error_struct_1.VALUE_ERROR = VALUE_ERROR_FLASH_write; // if there was an error this will be non-zero
}
}
void FLASH_init(void)
{
//FLASH(FCMD_ERASE_ALL_BLOCKS,0,0);
FLASH(FCMD_PROGRAM_PARTITION,0,0);
FLASH(FCMD_SET_FLEXRAM_FUNCTION,0,0);
}
Thanks
Pascal