--- /dev/null
+/*****************************************************************************/
+/* THIS SAMPLE CODE IS PROVIDED AS IS AND IS SUBJECT TO ALTERATIONS. FUJITSU */
+/* MICROELECTRONICS ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR */
+/* ELIGIBILITY FOR ANY PURPOSES. */
+/* (C) Fujitsu Microelectronics Europe GmbH */
+/*****************************************************************************/
+
+#include "flash.h"
+#include "mb91465k.h"
+
+static unsigned int IFlag;
+
+#pragma section CODE=IRAM,attr=CODE
+
+
+void FLASH_PrepareWriteHalfWordMode()
+{
+ /* Set FLASH Access Mode via BootROM Routine */
+ /* For details refer to the Hardware Manual or Data Sheet */
+#pragma asm
+ ST RP,@-R15
+ STM0 (R4,R5)
+ STM1 (R12)
+ LDI #0x01,R4 ; Set FLASH to 16Bit read/write Mode
+ LDI #0x04,R5 ; Go 4 times through delay loop (64MHz CLKB)
+ LDI #0xBF60,R12
+ CALL @R12
+ LDM1 (R12)
+ LDM0 (R4,R5)
+ LD @R15+,RP
+#pragma endasm
+
+ /* Set the FLASH Interface to Write Timing */
+ /* For details refer to the Hardware Manual or Data Sheet */
+ /* Setting shown here is for CLKB = 64MHz */
+ FMWT_ATD = 1;
+ FMWT_WEXH = 0;
+ FMWT_WTC = 8;
+}
+
+void FLASH_PrepareReadMode()
+{
+ /* Set FLASH Access Mode via BootROM Routine */
+ /* For details refer to the Hardware Manual or Data Sheet */
+#pragma asm
+ ST RP,@-R15
+ STM0 (R4,R5)
+ STM1 (R12)
+ LDI #0x00,R4 ; Set FLASH to 32Bit read/write Mode
+ LDI #0x04,R5 ; Go 4 times through delay loop (64MHz CLKB)
+ LDI #0xBF60,R12
+ CALL @R12
+ LDM1 (R12)
+ LDM0 (R4,R5)
+ LD @R15+,RP
+#pragma endasm
+
+ /* Set the FLASH Interface to Read Timing */
+ /* For details refer to the Hardware Manual or Data Sheet */
+ /* Setting shown here is for CLKB = 64MHz */
+ FMWT_ATD = 1;
+ FMWT_EQ = 3;
+ FMWT_WTC = 4;
+}
+
+
+unsigned char FLASH_SectorErase(unsigned int secadr)
+{
+ unsigned char flag = 0;
+ volatile unsigned int value = 0;
+
+ /* Disable Interrupts if necessary */
+ IFlag = FLASH_SaveDisableInterruptFlag();
+
+ /* Set FLASH access mode to 16Bit Write Mode */
+ FLASH_PrepareWriteHalfWordMode();
+
+ secadr |= 0x0003;
+
+ /* Start FLASH Sector Erase Sequence */
+ *hseq_1 = 0x00AA;
+ *hseq_2 = 0x0055;
+ *hseq_1 = 0x0080;
+ *hseq_1 = 0x00AA;
+ *hseq_2 = 0x0055;
+ *(unsigned short int *)secadr = 0x0030;
+
+ /* Wait for the Auto Algorithm to start */
+ while( !( *(unsigned short int *)secadr & SETIMR ) )
+ {
+ /* Feed the Hardware Watchdog */
+ HWWD_CL = 0;
+
+ /* Check for Pending Interrupts */
+ if( FLASH_CheckPendingInterrupt() )
+ {
+ /* Wait for Sector Erase Suspend */
+ FLASH_SuspendSectorErase(secadr);
+
+ /* Set FLASH access mode to 32Bit Read Mode */
+ FLASH_PrepareReadMode();
+
+ /* Restore the original Interrupt Flag */
+ FLASH_RestoreInterruptFlag(IFlag);
+
+ /* Keep on checking for pending Interrupts */
+ while( FLASH_CheckPendingInterrupt() ) HWWD_CL = 0;
+
+ /* Disable Interrupts if necessary */
+ IFlag = FLASH_SaveDisableInterruptFlag();
+
+ /* Set FLASH access mode to 16Bit Write Mode */
+ FLASH_PrepareWriteHalfWordMode();
+
+ /* Sector Erase Resume */
+ FLASH_ResumeSectorErase(secadr);
+ }
+ }
+
+ /* Wait for the Auto Algorithm to finish */
+ while( flag == 0 )
+ {
+ /* Feed Hardware Watchdog */
+ HWWD_CL = 0;
+
+ /* Check for Pending Interrupts */
+ if( FLASH_CheckPendingInterrupt() )
+ {
+ /* Sector Erase Suspend */
+ FLASH_SuspendSectorErase(secadr);
+
+ /* Set FLASH access mode to 32Bit Read Mode */
+ FLASH_PrepareReadMode();
+
+ /* Restore the original Interrupt Flag */
+ FLASH_RestoreInterruptFlag(IFlag);
+
+ /* Keep on checking for pending Interrupts */
+ while( FLASH_CheckPendingInterrupt() ) HWWD_CL = 0;
+
+ /* Disable Interrupts if necessary */
+ IFlag = FLASH_SaveDisableInterruptFlag();
+
+ /* Set FLASH access mode to 16Bit Write Mode */
+ FLASH_PrepareWriteHalfWordMode();
+
+ /* Sector Erase Resume */
+ FLASH_ResumeSectorErase(secadr);
+ }
+
+
+ /* Check the Hardware Sequence Flags */
+ if( ( *(unsigned short int *)secadr /* value */ & DPOLL ) )
+ {
+ flag = 1;
+ }
+ if( ( *(unsigned short int *)secadr /* value */ & TLOVER ) )
+ {
+ if( ( *(unsigned short int *)secadr /* value */ & DPOLL ) )
+ {
+ flag = 1;
+ }
+ else
+ {
+ /* Reset FLASH */
+ FLASH_ReadReset();
+
+ flag = 2;
+ }
+ }
+ }
+
+
+ /* Restore the original Interrupt Flag */
+ FLASH_RestoreInterruptFlag(IFlag);
+
+ /* Set FLASH access mode to 32Bit Read Mode */
+ FLASH_PrepareReadMode();
+
+ return flag;
+}
+
+unsigned char FLASH_SectorBlankCheck(unsigned int secaddr, unsigned int size)
+{
+ unsigned int count;
+ unsigned char empty_flag = 0;
+ unsigned int addr = secaddr;
+
+ /* Clear FIXE bit to see FLASH memory content instead of fixed reset vector */
+ FMCS_FIXE = 0;
+
+ for(count = 0; count < size; count ++)
+ {
+ /* Clear Hardware Watchdog */
+ HWWD_CL = 0;
+ if( *(unsigned int *)addr != 0xFFFFFFFF ) empty_flag = 1;
+ addr += 4;
+ }
+
+ /* Set FIXE bit to see fixed reset vector */
+ FMCS_FIXE = 1;
+
+ if( empty_flag != 0 )
+ {
+ return 2;
+ }
+
+ return 1;
+}
+
+unsigned char FLASH_WriteHalfWord(unsigned int adr, unsigned short int data)
+{
+ unsigned char flag = 0;
+
+ /* Disable Interrupts if necessary */
+ IFlag = FLASH_SaveDisableInterruptFlag();
+
+ /* Set FLASH access mode to 16Bit Write Mode */
+ FLASH_PrepareWriteHalfWordMode();
+
+ /* Start Write FLASH Sequence */
+ *hseq_1 = 0x00AA;
+ *hseq_2 = 0x0055;
+ *hseq_1 = 0x00A0;
+ *((volatile unsigned short int *)adr) = data;
+
+ /* Wait for the Auto Algorithm to finish */
+ while( flag == 0 )
+ {
+ /* Feed Hardware Watchdog */
+ HWWD_CL = 0;
+
+ if( ( *(volatile unsigned short int *)adr & DPOLL ) == (data & DPOLL) )
+ {
+ flag = 1;
+ }
+ if( ( *(volatile unsigned short int *)adr & TLOVER ) == TLOVER )
+ {
+ if( ( *(volatile unsigned short int *)adr & DPOLL ) == (data & DPOLL) )
+ {
+ flag = 1;
+ }
+ else
+ {
+ /* Reset FLASH (keep in mind 16Bit access to FLASH) */
+ *hseq_1 = 0x00F0; // Keep in Mind (16Bit access)
+
+ flag = 2;
+ }
+ }
+ }
+
+ /* Set FLASH access mode to 32Bit Read Mode */
+ FLASH_PrepareReadMode();
+
+ /* Restore the original Interrupt Flag */
+ FLASH_RestoreInterruptFlag(IFlag);
+
+ return flag;
+}
+
+
+unsigned char FLASH_ReadReset()
+{
+ *hseq_1 = 0x00F0;
+
+ return 1;
+}
+
+#pragma asm
+_FLASH_SaveDisableInterruptFlag:
+ STM0 (R0)
+ MOV PS,R4
+ LDI #0x00000010,R0
+ AND R0,R4 ; Store Original Flag
+ ANDCCR #0xFFFFFFEF ; Clear Interrupt Flag
+ LDM0 (R0)
+ RET
+#pragma endasm
+
+
+#pragma asm
+_FLASH_RestoreInterruptFlag:
+ STM0 (R0)
+ MOV PS,R0 ; Get current PS
+ OR R4,R0 ; Set Flag as saved
+ MOV R0,PS ; Write back PS
+ LDM0 (R0)
+ RET
+#pragma endasm
+
+
+unsigned char FLASH_SuspendSectorErase(unsigned int secaddr)
+{
+ /* Write Sector Erase Suspend Command */
+ *(volatile unsigned short int *)secaddr = 0x00B0;
+
+ /* Wait for the FLASH macro to suspend sector erase */
+ while(!(*(unsigned short int *)secaddr /* value */ & DPOLL) && (*(unsigned short int *)secaddr /* value */ & SETIMR))
+ {
+ HWWD_CL=0;
+ }
+
+ return 1;
+}
+
+unsigned char FLASH_ResumeSectorErase(unsigned int secaddr)
+{
+ /* Write the Sector Erase Resume Command */
+ *(volatile unsigned short int *)secaddr = 0x0030;
+
+ /* Wait for the FLASH Macro to resume sector erase */
+ while((*(unsigned short int *)secaddr /*value */ & DPOLL) && !(*(unsigned short int *)secaddr /*value */ & SETIMR))
+ {
+ HWWD_CL=0;
+ }
+
+ return 1;
+}
+
+unsigned char FLASH_CheckPendingInterrupt()
+{
+ /* Poll for Pending Interrupts which are needed here */
+ if(TMCSR0_UF) return 1; /* in this sample the only interrupt source supervised is Reload Timer 0 */
+
+ /* and return 1 when an Interrupt is pending */
+ return 0;
+}