Hi, I am having a little issue in accessing the flash memory on the S12X module. My requirement is to compute md5 on flash memory of the s12xd256 module. So my idea was to start reading all the locations, store them in a temporary buffer. And once the buffer is full, compute md5 on them and clear the contents of the buffer. I have implemented a very similar function on the s12 module which works flawlessly, but in S12x, the moment my device tries to access the flash memory, it restarts. I am attaching the snippet below.
Md5.SubpageSize = 16384/128;
if(page<32)
{
if((subpage*Md5.SubpageSize)<16384)
{
old_PPAGE = PPAGE;
PPAGE = 0xE0 + page;
for(j=0; j<g_Md5.SubpageSize; j+=64)
{
for(k=0; k<32; ++k) // just copy flash location ro RAM buffer
{
flash_buf[k] = *(word*)(0x8000+(subpage*g_Md5.SubpageSize)+j+(k*2)); /* 'word flash_buf[32]' is a temp buffer */
}
block_ptr = (byte*) &flash_buf[0];
MD5Update(&context, block_ptr, 64);
}
PPAGE = old_PPAGE;
++subpage;
}
else
{
if (page == 7){
page = 23; /* Skip to page 23, since page 8-23 are not used*/
}
subpage = 0;
++page;
}
}
Thanks.
Solved! Go to Solution.
Yes, as Edward already mentioned directly change of PPAGE is not very save.
I created simple example code for CRC checksum calculation over paged flash (for S12G). It doesn't need to be in non banked flash.
You can take it as inspiration:
unsigned char crc_sum;
unsigned long j, ptr;
unsigned int k;
crc_sum = 0xFF; //CRC initial value
for(j=0x010000;j<=0x0E0000;j=j+0x010000) //PPAGE increment (except last page)
{
for(k=0x8000;k<=0xBFFF;k++) //Address increment
{
ptr = j+k; //Complete address
crc_sum= CheckSumByteCRC8(crc_sum, *((unsigned char *far)ptr) , DEFAULT_CRC8_CHECKSUM);
}
}
j=0x0F0000; //last page
for(k=0x8000;k<=0xBEFF;k++) //Address increment - without reset vectors
{
ptr = j+k; //Complete address
crc_sum= CheckSumByteCRC8(crc_sum, *((unsigned char *far)ptr) , DEFAULT_CRC8_CHECKSUM);
}
if (crc_sum == CHECKSUM_STORAGE_CRC8) PTT_PTT7 = 0; //if checksum ok, LED on
FYI: CodeWarrior linker is able calculate checksum automatically (according definition in *.prm file).
Example codes for checksum calculation you can find on your disk in CodeWarrior installation directory. Default path:
"c:\Program Files\Freescale\CWS12v5.1\(CodeWarrior_Examples)\HC12\Checksums\.."
Possible CHECKSUM_METHOD= "METHOD_CRC_CCITT"|"METHOD_CRC8"|"METHOD_CRC16"|"METHOD_CRC32"|"METHOD_ADD"|"METHOD_XOR".
CheckSumByteCRC8 is function from "c:\Program Files\Freescale\CWS12v5.1\lib\hc12c\src\checksum.c" file.
If you will need complete example code, please let me know, or create new service request at Freescale support page.
Isn't this code allocated in banked memory?
Yes the code is allocated in the banked memory. Pardon my naiveness, I am a little new to the microcontroller programming, Can you please let me know what is wrong in the following code and how should I implement it ?.Is it something to do with using PPAGE since the code is allocated using it. So if that, should I use GPAGE instead ?
You can't manipulate PPAGE register when executing code in banked memory. Try flipping a page, which you are reading and continue reading from the same position on different page...
But I wonder how similar function would work on S12. Was it made nonbanked? Did you use small memory model?
To fix it, just allocate routine with PPAGE=xx and PPAGE = old_PPAGE in nonbanked memory.
#pragma CODE_SEG __NEAR_SEG NON_BANKED
<put your routine here>
#pragma CODE_SEG DEFAULT
If you declare prototype of this function anywhere, prototype also should be put between identical pragmas.
I am using cosmic compiler and moreover, I ended up making a very silly error which I realized after my first reply to you. After writting that the code is allocated in the bank memory, I realised what was messing up. All I did was change the md5 code to unbanked memory in the linker file (.lkf). It started working. Thanks for pointing that out :smileyhappy: