Device Driver for RAMTRON FM25W256 SPI-driven FRAM Uses SPI peripheral at 10MHz Based on fast SPI routines

Dependents:   RAMTRON_FM25W256

Revision:
0:2290931492e7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fm25w256.cpp	Thu Apr 05 10:15:52 2012 +0000
@@ -0,0 +1,191 @@
+#include "fm25w256.h"
+#include "mbed.h"
+
+/* ===================================================================
+    routine:    FM25W_SSP1_Init
+    purpose:    Configures the LPC1768's SSP1 peripheral for 
+                communication with Ramtron FM25W256 FRAM memory
+    parameters:    none
+    returns:    nothing
+    date:        2012-04-05
+    author:        Stefan Guenther    
+
+    * hardware connection scheme: *
+    
+    mbed                                           FRAM
+    (LPC1768)
+    --------+                                    +---------
+            |    +Vcc            _____          |
+            |      o      +-----| 4k7 |---------+ !WP
+            |      |      |                     |
+     VCC    +------+------+                     |               
+            |             |      _____          |     
+            |             +-----| 4k7 |-------- + !HOLD
+            | <CLK>                                |
+     P0.7   +--->--------------------------->---+ SCK
+             | <MISO>                            |
+     P0.8      +---<---------------------------<---+ SO
+             | <MOSI>                            | 
+     P0.9   +--->--------------------------->---+ SI
+              | <!SSL>                            |
+     P0.6   +--->--------------------------->---+ !CS
+            |                                    |
+     GND    +------------------+----------------+ GND
+            |                   |                |
+    --------+                   o                +---------
+                              0V                              
+    Keep traces as short as possible - SPI frequency is 10MHz!
+  -------------------------------------------------------------------*/
+void FM25W_SSP1_Init(void)
+{
+    LPC_SC->PCLKSEL0|=(1<<20);         //SSP clock = 1x System Clock 
+    LPC_SC->PCONP |= BIT10;            //enable power to SSP1 peripheral
+    //P0.6 -> SSEL
+    //P0.7 -> SCK
+    //P0.8 -> MISO
+    //P0.9 -> MOSI
+    LPC_PINCON->PINSEL0 &=~0xFC000;   //reset GPIO functions for needed portpins                                    
+    LPC_PINCON->PINSEL0 |= 0xA8000;   //set GPIO functions to SSP1
+    LPC_SSP1->CPSR=11;                //SSP clock divider (results in 10MHz SPI Clk)
+    LPC_SSP1->CR0=7;//|0x80|0x40;     //FRF=SPI, DSS=8, SPO=1, SPH=1                                    
+    LPC_SSP1->CR1 &=~BIT2;            //SSP1 is master
+    LPC_SSP1->CR1 |= BIT1;            //enable SSP1 peripheral (SSE bit)    
+    LPC_PINCON->PINSEL0 &=~0x3000;    //p8 [P0.6] is Slave Select (software driven)
+    LPC_GPIO0->FIODIR |= BIT6;        //P0.6 is output
+    SSL1;
+}
+
+
+/* ===================================================================
+    routine:    FM25W_ReadByte
+    purpose:    Reads a single byte from specified memory address
+    parameters:    <iAddress>  Memory address to read
+    returns:    Memory content
+    date:        2012-04-05
+    author:        Stefan Guenther
+  -------------------------------------------------------------------*/
+unsigned char FM25W_ReadByte(unsigned int iAddress)
+{
+    unsigned char retVal=0;
+    while(!(LPC_SSP1->SR&BIT0));            //wait for TX FIFO to get empty
+    SSL0;
+    LPC_SSP1->DR = READ;
+    LPC_SSP1->DR = (iAddress >> 8) & 0xFF;  //Send top address byte to read from
+    LPC_SSP1->DR =  iAddress       & 0xFF;  //Send Middle address byte to read from    
+    LPC_SSP1->DR = 0;
+    while(LPC_SSP1->SR&BIT4);               //wait for TX to end
+    while(LPC_SSP1->SR&BIT2)                //read out RX FIFO
+        retVal = LPC_SSP1->DR;              //last FIFO entry is our data byte
+    SSL1;
+    return(retVal);
+}
+
+/* ===================================================================
+    routine:    FM25W_WriteByte
+    purpose:    Writes a single byte to specified memory address
+    parameters:    <iAddress>  Memory address to write to
+                <cByte>     Data to be written
+    returns:    nothing
+    date:        2012-04-05
+    author:        Stefan Guenther
+  -------------------------------------------------------------------*/
+void FM25W_WriteByte(unsigned int iAddress, unsigned char cByte)
+{    
+    while(!(LPC_SSP1->SR&BIT0));            //wait for TX FIFO to get empty
+    SSL0;
+    LPC_SSP1->DR = WREN;                    //WREN has to be written prior to
+                                            //each write access to FRAM
+    while(LPC_SSP1->SR&BIT4);               //wait for TX to end    
+    SSL1;
+    while(LPC_SSP1->SR&BIT2)                //clear RX FIFO
+        if(LPC_SSP1->DR);                   
+    SSL0;    
+    LPC_SSP1->DR = WRITE;
+    LPC_SSP1->DR = (iAddress >> 8) & 0xFF;  //Send top address byte to read from
+    LPC_SSP1->DR =  iAddress       & 0xFF;  //Send low address byte to read from    
+    LPC_SSP1->DR = cByte;
+    while(LPC_SSP1->SR&BIT4);               //wait for TX to end
+    while(LPC_SSP1->SR&BIT2)                //clear RX FIFO
+        if(LPC_SSP1->DR);                   
+    SSL1; 
+}
+
+/* ===================================================================
+    routine:    FM25W_WriteBlock
+    purpose:    Writes a block of data, starting at specified
+                memory address
+    parameters:    <iAddress>  First memory address to be written
+                <*ptrBlock> Pointer to data block to be written
+                <iCount>    Length (in bytes) of data block
+    returns:    nothing
+    date:        2012-04-05
+    author:        Stefan Guenther
+  -------------------------------------------------------------------*/
+void FM25W_WriteBlock(unsigned int iAddress, unsigned char *ptrBlock, unsigned int iCount)
+{    
+    int x;
+    while(!(LPC_SSP1->SR&BIT0));            //wait for TX FIFO to get empty
+    SSL0;
+    LPC_SSP1->DR = WREN;                    //unlock FRAM for writing
+    while(LPC_SSP1->SR&BIT4);               //wait for TX to end    
+    SSL1;
+    while(LPC_SSP1->SR&BIT2)                //clear RX FIFO
+        if(LPC_SSP1->DR);                   
+    SSL0;    
+    LPC_SSP1->DR = WRITE;                   //send write command
+    LPC_SSP1->DR = (iAddress >> 8) & 0xFF;  //set start adress of block
+    LPC_SSP1->DR =  iAddress       & 0xFF;           
+    for(x=0; x<iCount; x++)     
+    {        
+        while(!(LPC_SSP1->SR&BIT1));        //wait as TX FIFO is full
+        
+        LPC_SSP1->DR = *ptrBlock;
+        ptrBlock++;        
+    }    
+    while(LPC_SSP1->SR&BIT4);               //wait for TX to end   
+    SSL1;
+    while(LPC_SSP1->SR&BIT2)                //clear RX FIFO
+        if(LPC_SSP1->DR);  
+}
+
+/* ===================================================================
+    routine:    FM25W_ReadBlock
+    purpose:    Reads a block of data, starting at specified
+                memory address
+    parameters:    <iAddress>  First memory address to be read
+                <*ptrBlock> Pointer to local RAM for data block
+                <iCount>    Length (in bytes) of data block to read
+    returns:    nothing
+    date:        2012-04-05
+    author:        Stefan Guenther
+  -------------------------------------------------------------------*/
+void FM25W_ReadBlock(unsigned int iAddress, unsigned char *ptrBlock, unsigned int iCount)
+{
+    int x;
+    
+    while(LPC_SSP1->SR&BIT2)                //clear RX FIFO
+        if(LPC_SSP1->DR);  
+    while(!(LPC_SSP1->SR&BIT0));            //wait for TX FIFO to get empty
+    
+    SSL0;    
+    
+    LPC_SSP1->DR = READ;
+    LPC_SSP1->DR = (iAddress >> 8) & 0xFF;  //send upper address byte to read from
+    LPC_SSP1->DR =  iAddress       & 0xFF;  //send lower address byte to read from    
+    while(LPC_SSP1->SR&BIT4);               //wait for TX FIFO to get empty
+    x = LPC_SSP1->DR;                       //clear RX FIFO
+    x = LPC_SSP1->DR;
+    x = LPC_SSP1->DR;   
+        
+    for(x=0; x<iCount; x++)
+    {        
+        LPC_SSP1->DR = 0;                   //send first dummy byte    
+        while(LPC_SSP1->SR&BIT4);           //wait for TX FIFO to get empty        
+        *ptrBlock = LPC_SSP1->DR;           //last FIFO entry is our data byte                
+        ptrBlock++;        
+    }        
+    SSL1;
+    while(LPC_SSP1->SR&BIT2)                //clear RX FIFO
+        if(LPC_SSP1->DR);                        
+} 
+ 
\ No newline at end of file