Device Driver for RAMTRON FM25W256 SPI-driven FRAM Uses SPI peripheral at 10MHz Based on fast SPI routines
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); }