summaryrefslogtreecommitdiff
path: root/cpu/at91rm9200/at45.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/at91rm9200/at45.c')
-rw-r--r--cpu/at91rm9200/at45.c145
1 files changed, 120 insertions, 25 deletions
diff --git a/cpu/at91rm9200/at45.c b/cpu/at91rm9200/at45.c
index cf456fb..9dfe560 100644
--- a/cpu/at91rm9200/at45.c
+++ b/cpu/at91rm9200/at45.c
@@ -26,6 +26,7 @@
#include <dataflash.h>
#define SPI_CLK 5000000
+#define AT91C_TIMEOUT_WRDY 200000
#define AT91C_SPI_PCS0_SERIAL_DATAFLASH 0xE /* Chip Select 0 : NPCS0 %1110 */
#define AT91C_SPI_PCS3_DATAFLASH_CARD 0x7 /* Chip Select 3 : NPCS3 %0111 */
@@ -145,10 +146,17 @@ AT91S_DataFlashStatus AT91F_DataFlashSendCommand(
/* fill the command buffer */
pDataFlash->pDataFlashDesc->command[0] = OpCode;
- pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
- pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
- pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
- pDataFlash->pDataFlashDesc->command[4] = 0;
+ if (pDataFlash->pDevice->pages_number >= 16384) {
+ pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x0F000000) >> 24);
+ pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x00FF0000) >> 16);
+ pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((adr & 0x0000FF00) >> 8);
+ pDataFlash->pDataFlashDesc->command[4] = (unsigned char)(adr & 0x000000FF);
+ } else {
+ pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
+ pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
+ pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
+ pDataFlash->pDataFlashDesc->command[4] = 0;
+ }
pDataFlash->pDataFlashDesc->command[5] = 0;
pDataFlash->pDataFlashDesc->command[6] = 0;
pDataFlash->pDataFlashDesc->command[7] = 0;
@@ -205,8 +213,7 @@ AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDe
do {
AT91F_DataFlashGetStatus(pDataFlashDesc);
timeout--;
- }
- while( ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout > 0) );
+ } while( ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout > 0) );
if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
return DATAFLASH_ERROR;
@@ -230,6 +237,7 @@ AT91S_DataFlashStatus AT91F_DataFlashContinuousRead (
unsigned char *dataBuffer,
int sizeToRead )
{
+ AT91S_DataFlashStatus status;
/* Test the size to read in the device */
if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
return DATAFLASH_MEMORY_OVERFLOW;
@@ -239,8 +247,9 @@ AT91S_DataFlashStatus AT91F_DataFlashContinuousRead (
pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
+ status = AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
/* Send the command to the dataflash */
- return(AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src));
+ return(status);
}
@@ -259,13 +268,17 @@ AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(
unsigned int dest,
unsigned int SizeToWrite)
{
+ int cmdsize;
pDataFlash->pDataFlashDesc->tx_data_pt = src ;
pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
pDataFlash->pDataFlashDesc->rx_data_pt = src;
pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
+ cmdsize = 4;
/* Send the command to the dataflash */
- return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, 4, dest));
+ if (pDataFlash->pDevice->pages_number >= 16384)
+ cmdsize = 5;
+ return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, cmdsize, dest));
}
@@ -282,14 +295,17 @@ AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
unsigned char BufferCommand,
unsigned int page)
{
+ int cmdsize;
/* Test if the buffer command is legal */
if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF))
return DATAFLASH_BAD_COMMAND;
/* no data to transmit or receive */
pDataFlash->pDataFlashDesc->tx_data_size = 0;
-
- return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, page*pDataFlash->pDevice->pages_size));
+ cmdsize = 4;
+ if (pDataFlash->pDevice->pages_number >= 16384)
+ cmdsize = 5;
+ return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, page*pDataFlash->pDevice->pages_size));
}
@@ -310,6 +326,7 @@ AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer (
unsigned int bufferAddress,
int SizeToWrite )
{
+ int cmdsize;
/* Test if the buffer command is legal */
if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE))
return DATAFLASH_BAD_COMMAND;
@@ -324,14 +341,22 @@ AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer (
/* Send first Write Command */
pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
pDataFlash->pDataFlashDesc->command[1] = 0;
- pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
- pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
-
+ if (pDataFlash->pDevice->pages_number >= 16384) {
+ pDataFlash->pDataFlashDesc->command[2] = 0;
+ pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
+ pDataFlash->pDataFlashDesc->command[4] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
+ cmdsize = 5;
+ } else {
+ pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
+ pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
+ pDataFlash->pDataFlashDesc->command[4] = 0;
+ cmdsize = 4;
+ }
pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
- pDataFlash->pDataFlashDesc->tx_cmd_size = 4 ;
+ pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize ;
pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
- pDataFlash->pDataFlashDesc->rx_cmd_size = 4 ;
+ pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize ;
pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer ;
pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer ;
@@ -341,6 +366,51 @@ AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer (
return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
}
+/*------------------------------------------------------------------------------*/
+/* Function Name : AT91F_PageErase */
+/* Object : Erase a page */
+/* Input Parameters : DataFlash Service */
+/* : Page concerned */
+/* : */
+/* Return value : State of the dataflash */
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_PageErase(
+ AT91PS_DataFlash pDataFlash,
+ unsigned int page)
+{
+ int cmdsize;
+ /* Test if the buffer command is legal */
+ /* no data to transmit or receive */
+ pDataFlash->pDataFlashDesc->tx_data_size = 0;
+
+ cmdsize = 4;
+ if (pDataFlash->pDevice->pages_number >= 16384)
+ cmdsize = 5;
+ return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_ERASE, cmdsize, page*pDataFlash->pDevice->pages_size));
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name : AT91F_BlockErase */
+/* Object : Erase a Block */
+/* Input Parameters : DataFlash Service */
+/* : Page concerned */
+/* : */
+/* Return value : State of the dataflash */
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_BlockErase(
+ AT91PS_DataFlash pDataFlash,
+ unsigned int block)
+{
+ int cmdsize;
+ /* Test if the buffer command is legal */
+ /* no data to transmit or receive */
+ pDataFlash->pDataFlashDesc->tx_data_size = 0;
+ cmdsize = 4;
+ if (pDataFlash->pDevice->pages_number >= 16384)
+ cmdsize = 5;
+ return(AT91F_DataFlashSendCommand (pDataFlash, DB_BLOCK_ERASE,cmdsize, block*8*pDataFlash->pDevice->pages_size));
+}
/*------------------------------------------------------------------------------*/
/* Function Name : AT91F_WriteBufferToMain */
@@ -355,6 +425,7 @@ AT91S_DataFlashStatus AT91F_WriteBufferToMain (
unsigned char BufferCommand,
unsigned int dest )
{
+ int cmdsize;
/* Test if the buffer command is correct */
if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
(BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
@@ -365,8 +436,11 @@ AT91S_DataFlashStatus AT91F_WriteBufferToMain (
/* no data to transmit or receive */
pDataFlash->pDataFlashDesc->tx_data_size = 0;
+ cmdsize = 4;
+ if (pDataFlash->pDevice->pages_number >= 16384)
+ cmdsize = 5;
/* Send the command to the dataflash */
- return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, dest));
+ return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, dest));
}
@@ -391,10 +465,18 @@ AT91S_DataFlashStatus AT91F_PartialPageWrite (
/* Read the contents of the page in the Sram Buffer */
AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
- AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+ AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
/*Update the SRAM buffer */
AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size);
- AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+
+ AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+
+ /* Erase page if a 128 Mbits device */
+ if (pDataFlash->pDevice->pages_number >= 16384) {
+ AT91F_PageErase(pDataFlash, page);
+ /* Rewrite the modified Sram Buffer in the main memory */
+ AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+ }
/* Rewrite the modified Sram Buffer in the main memory */
return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, (page*pDataFlash->pDevice->pages_size)));
@@ -402,7 +484,7 @@ AT91S_DataFlashStatus AT91F_PartialPageWrite (
/*------------------------------------------------------------------------------*/
-/* Function Name : AT91F_DataFlashWrite_Overloaded */
+/* Function Name : AT91F_DataFlashWrite */
/* Object : */
/* Input Parameters : <*src> = Source buffer */
/* : <dest> = dataflash adress */
@@ -415,6 +497,8 @@ AT91S_DataFlashStatus AT91F_DataFlashWrite(
int size )
{
unsigned int length;
+ unsigned int page;
+ unsigned int status;
AT91F_SpiEnable(pDataFlash->pDevice->cs);
@@ -431,7 +515,7 @@ AT91S_DataFlashStatus AT91F_DataFlashWrite(
if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
return DATAFLASH_ERROR;
- AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+ AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
/* Update size, source and destination pointers */
size -= length;
@@ -441,10 +525,21 @@ AT91S_DataFlashStatus AT91F_DataFlashWrite(
while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) {
/* program dataflash page */
- if(!AT91F_DataFlashPagePgmBuf(pDataFlash, src, dest, pDataFlash->pDevice->pages_size ))
+ page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
+
+ status = AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, 0, pDataFlash->pDevice->pages_size);
+ AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+
+ status = AT91F_PageErase(pDataFlash, page);
+ AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+ if (!status)
+ return DATAFLASH_ERROR;
+
+ status = AT91F_WriteBufferToMain (pDataFlash, DB_BUF1_PAGE_PGM, dest);
+ if(!status)
return DATAFLASH_ERROR;
- AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+ AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
/* Update size, source and destination pointers */
size -= pDataFlash->pDevice->pages_size ;
@@ -458,7 +553,7 @@ AT91S_DataFlashStatus AT91F_DataFlashWrite(
if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
return DATAFLASH_ERROR;
- AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+ AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
}
return DATAFLASH_OK;
}
@@ -480,13 +575,13 @@ int AT91F_DataFlashRead(
AT91F_SpiEnable(pDataFlash->pDevice->cs);
- if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
+ if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
return -1;
while (size) {
SizeToRead = (size < 0x8000)? size:0x8000;
- if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
+ if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
return -1;
if (AT91F_DataFlashContinuousRead (pDataFlash, addr, buffer, SizeToRead) != DATAFLASH_OK)