I want to erase sectors in flash at 0x48000,
and I am unable to write to an adress in the sector.
How do I write to address 0x48000 to initiate the erase procedure?
What goes here?
FCMD = mPageErase; // Command to Page Erase
FSTAT_FCBEF = 1; // Execute command
{asm nop;} // Delay
{asm nop;}
{asm nop;}
{asm nop;}
etc... etc ...
Is PPAGE needed?
Please assist, I am stuck.
Thanks,
Anders J
Maybe I'm wrong, but from what I have understood, even if you have three registers of 8 bits each for the pointer, only the "lower" 17 bits are writable, allowing the user to point every address in the 128KB range, corresponding to 1FFFF hexadecimal. So, you can't write to address 48000 simply because the Memory Management Unit LAP registers don't support such a large addressing mode.
You have three LAP registers:
- LAP0 (bits LA7 to LA0) accepts values from 00 hexadecimal to FF hexadecimal
- LAP1 (bits LA15 to LA8) accepts values from 00 hexadecimal to FF hexadecimal
- LAP2 (bit LA16) accepts values 0 or 1.
If you set all the bits you have 1FFFF hexadecimal, or 131071 decimal, way lower than 48000 hexadecimal.
P. S.: I'm still learning a lot about microcontrollers, so I can be wrong over the entire topic
... Maybe users like bigmac or peg can correct this post
!
0x48000 is paged / banked address pointer, where 4 is PPAGE and 0x8000 - bottom CPU address of PPAGE window. Linear address, corresponding to paged address 0x48000 is 4*sizeof(PPAGE window) + 0x8000 % sizeof(PPAGE window), which is 4*0x4000+0 = 0x10000. This will perfectly fit LAP.
Where are allocated your flash routines? Flash is not readable while it is being erased/programmed, so you can't run code from flash you are going to erase. DZ128 probably has two or more flash banks, so it may be that your flash routines allocated in flash work for half of available flash and fail for another half of flash. Try copying relevant parts to RAM and execute from there. Search forums for how you could move flash routine to RAM.
BTW FSTAT_FCBEF = 1; <-- this is wrong way to clear FSTAT flag. Since FSTAT has more than one "write one to clear" flags, FSTAT_FCBEF=1 will clear all flags that are set. You need to replace you wrong code with this
FSTAT = FSTAT_FCBEF_MASK;
I have my code in banked rom at 0x2180, to erase at 0x48000.
My main issue is how to set up a pointer to 0x48000 and then write something to it.
I am not sure if I need to use PPAGE,
or if it is handled by the compiler, if at all needed.
Apart from saving a few bytes, what is the difference between setting bit 7
with FSTAT = FSTAT_FCBEF_MASK like I do,
and writing an entire byte with the mask as you suggest.
Anders
You may use either LAP or switch and restore PPAGE. How to use LAP is shown in CW example. Please find DEMOQE128_LAP_Dictionary in CW Examples folder. .
When switching PPAGE, you shold provide that your routine is located in nonbanked flash (not within PPAGE window 0x8000-0xBFFF). For banked applications also you need to restore PPAGE on exit from your nonbanked program/erase routine.
Like I wanted to say, you can't use C bitfields or bit set code with FSTAT register, because this may write more ones to FSTAT register and clear flags, you are not intended to clear. For example FSTAT |= FSTAT_PVIOL_MASK and FSTAT_PVIOL=1 both will attempt to write one to FCBEF bit and try to launch flash command!
Bit set and bit fields can be used only with flags, that are packed one flag per flags register, and still with some restrictions. Ack bits like IRQACK, LVWACK and others have no problems at all. Toggling bits in their registers won't write one to ACK bit, which read always 0. But what about comparator bit ACF? Yes, fine, you can set it to clear without any side effects. But what about toggling other bits, for example ACIE? Certainly it will clear ACF and you may loose important interrupt event if not done properly, making write to ACMPxSC with ACF bit cleared, like this to clear ACIE
ACMP1SC = ACMP1SC & ~(ACMP1SC_ACIE_MASK | ACMP1SC_ACF_MASK);
or this to set ACIE
ACMP1SC = (ACMP1SC | ACMP1SC_ACIE_MASK) & ~ACMP1SC_ACF_MASK;