PIC-WEB flash memory page address - why bit shifted?

Started by Joho, December 14, 2015, 09:13:24 PM

Previous topic - Next topic

Joho

We're working with a PIC-WEB, which uses Atmel AT45D011 flash memory.  We're having troubles with data getting corrupted in memory locations during flash writes.  We write to flash at a particular address, and the data is written properly to our specified address.  But it is also getting copied elsewhere, exactly one page ahead (+264 bytes) in flash memory. 

So I'm trying to understand the write process in all the SPIFlash* functions in SPIFlash_PICWEB.c.  The function WriteBufferToMainMemory has a line whose purpose I don't understand.  The code is:

page = address/264;
page<<=1;

I understand the first line fine... it gets the page number from the user-specified address.  But, why would I then bit-shift this?  Doesn't that just double the page number?  What if I'm trying to access an odd-numbered page, or if I specify an address on high page number (256 or higher)?  Then doubling it would actually put the address out of the physical range of the Atmel, which has only 512 pages.

What is the purpose of this bit-shifting line?   

Thanks

Stanimir5F

Hello, Joho!

I must admit this is a very, very good question! And at first when I read your question I felt a little bit embarrassed since I'm the developer of this project and I'm supposed to know the reason behind this but I didn't. Anyway - this patch was made by one of my colleagues who left our company years ago but this patch (made for the Atmel flash memory) was left like a legacy and I always used it as it is, without looking at its content. So when I saw your question I asked myself the same question - what is the purpose of this, but I was sure it has purpose. So I start looking for the answer and I found this:

AT45DB011 datasheet

Take a look at page 16, the description of "Buffer to Main Memory Page Program with Built-In Erase" (83H). There you can see how the address is sent via SPI interface. First byte is the opcode (83H) and the next two bytes represent the page number. The catch here is that the address is 9 bits (which is fine) BUT it is not sent as I expected - the high byte as it is and then the low byte:

(x  x  x  x  x  x  x  A8)
(A7 A6 A5 A4 A3 A2 A1 A0)


but instead it is shifted:
(x  x  x  x  x  x  A8 A7)
(A6 A5 A4 A3 A2 A1 A0 x )


And if you take a look in the code a little bit below in the same function there is this fragment (in the SPIFlash.c file):
//6 reserved + 2 high address
SPITransfer((*((unsigned char*)&page+1)));

//7 low address bits + 1 don't care
SPITransfer(((unsigned char)page));


Here you can see how the high 8 bits of the page number (actually this byte consist only the two high bits of the page) are sent. And then they are followed by the the rest (7 bits + 1 don't care) of the page number.

So that's why it is shifted. The purpose is not to double the page number, but to make sending the number via SPI easier.

I hope that helps you.

Best regards!
Stan, Olimex
May the Source be with You!

Joho

Thank you, it definitely does help!

I should have read the data sheet more closely.  I guess it's back to the drawing board to figure out this memory glitch.

Stanimir5F

I'm glad it helped you and I thank you too. I never thought about that and it's something good to know. :)
May the Source be with You!