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

Dependents:   RAMTRON_FM25W256

fm25w256.cpp

Committer:
elmicro
Date:
2012-04-05
Revision:
0:2290931492e7

File content as of revision 0:2290931492e7:

#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);                        
}