Device Driver for RAMTRON FM25W256 SPI-driven FRAM Uses SPI peripheral at 10MHz Based on fast SPI routines
Diff: fm25w256.cpp
- 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