Author Topic: Low level SPI memory access  (Read 33461 times)

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Low level SPI memory access
« on: June 03, 2008, 04:48:36 PM »
Hi mark,
  I have 1 Atmel SPI AT45041 memory chip on CS0, and would like to access it by Page Number only. I am converting some code I have used on another processor, where I simply use the page numbers. I simply read in a page to internal buffer, modify it, and write the page back. Is there low level commands to read in a page, write to a page etc...

Thanks
neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3244
    • View Profile
    • uTasker
Re: Low level SPI memory access
« Reply #1 on: June 03, 2008, 08:44:55 PM »
Hi Neil

At the lowest level the interface does work with commands, pages and offsets in pages.
Although it is local to the driver, you could use of it by making it global or by writing a cover function to use it:

Code: [Select]
static void fnSPI_command(unsigned char ucCommand, unsigned long ulPageNumberOffset, volatile unsigned char *ucData, MAX_FILE_LENGTH DataLength);
ucCommand is the chip command (like delete a page, or copy a page etc.).
ulPageNumberOffset is the page number and optional offset (depending in command)
ucData is only used for read and writes, where the length is DataLength

Examples:
fnSPI_command(WRITE_BUFFER_1, usPageOffset, _EXTENDED_CS ucData, usDataLength);
fnSPI_command(PROG_FROM_BUFFER_1, usPageNumber, _EXTENDED_CS 0, 0);

Note that, if using multiple chips a further parameter (_EXTENDED_CS) is also used to identify the chip. This is a dummy define when only one chip is used.

Regards

Mark

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: Low level SPI memory access
« Reply #2 on: June 04, 2008, 11:23:41 AM »
Hi Mark,
  Thanks for the above.

I have added 2 functions to the M5223x.c file to read and write to a page. I done the following:

void WriteToPage(unsigned long ulPageNumberOffset, volatile unsigned char *ucData)
{   
   fnSPI_command(WRITE_BUFFER_1, ulPageNumberOffset, ucData,SPI_FLASH_PAGE_LENGTH);
   fnSPI_command(ERASE_PROG_FROM_BUFFER_1, ulPageNumberOffset, ucData,SPI_FLASH_PAGE_LENGTH);
}

void ReadFromPage(unsigned long ulPageNumberOffset, volatile unsigned char *ucData)
{   
   fnSPI_command(CONTINUOUS_ARRAY_READ, ulPageNumberOffset << 9, ucData,SPI_FLASH_PAGE_LENGTH);
}


It works fine, but I wanted to check with you to make sure that there wont be any problems doing the above.

Thanks
neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3244
    • View Profile
    • uTasker
Re: Low level SPI memory access
« Reply #3 on: June 04, 2008, 12:12:22 PM »
Hi Neil

This looks good.

The read could however also be performed using the standard interface:
extern void fnGetParsFile(unsigned char *ParLocation, unsigned char *ptrValue, MAX_FILE_LENGTH Size);

where *ParLocation is a page boundary address and Size is SPI_FLASH_PAGE_LENGTH


The write could be perfomred by using
extern int fnWriteBytesFlash(unsigned char *ucDestination, unsigned char *ucData, MAX_FILE_LENGTH Length)
where *ucDestination is a page boundary address and length is SPI_FLASH_PAGE_LENGTH, however there is a difference in this case. This function uses PROG_FROM_BUFFER_1 rather than ERASE_PROG_FROM_BUFFER_1, meaning that it can set bits to '0' but not to '1' (if already zero). Since the routines are compatible between 'normal' FLASH and SPI FLASH this is the same restriction as with 'normal' FLASH and is handled by first performing a delete of the page if the delete is required (note that this is also specific to the Atmel FLASH device and other types can not necessarily support such a command). The advantage of the PROG_FROM_BUFFER_1 is that it is much faster than the ERASE_PROG_FROM_BUFFER_1 method since it doesn't always have an integrated erase phase which is executed irrespective of whether it is actually required. On teh other hand, the advantage of the ERASE_PROG_FROM_BUFFER_1 is that the chip automates the process and so the user doesn't have to know whether the erase phase is required or not. As I mentioned above, this is a special command in the ATMEL chip so isn't used in the standard interface driver since it would not allow compatibility between different chip types - presently we have ATMEL and ST support and the user interface is compatible, meaning that the chip types can be swapped without any user code needing to be changed (apart from configuring for the correct chip type...).

Further, the ATMEL has 2 page buffers and also compare functions which can - in special cases - be nice to have. These functions are also not supported by the generic interface but the low level method can be easily extended to make use of them. Specifically I like that fact that you can use the page buffers in the ATMEL to store data while the FLASH chip is actively deleting or writing and this can be a powerful feature in high speed data recording applications. The ST chips, for example, are a bit more restictive (they use the CS line to start programming and erase cycles) in certain applications - not that they are not usable, but they may involve quite different low level solutions. On the other hand, without the double page buffers, they are probably a bit cheaper (haven't actually checked this though...)

Regards

Mark