diff options
Diffstat (limited to 'cpu/at91rm9200')
-rw-r--r-- | cpu/at91rm9200/at45.c | 145 |
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) |