Device Driver for RAMTRON FM25W256 SPI-driven FRAM Uses SPI peripheral at 10MHz Based on fast SPI routines
fm25w256.cpp@0:2290931492e7, 2012-04-05 (annotated)
- Committer:
- elmicro
- Date:
- Thu Apr 05 10:15:52 2012 +0000
- Revision:
- 0:2290931492e7
Initial Revision with Read Block, Write Block, Read Byte, Write Byte
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
elmicro | 0:2290931492e7 | 1 | #include "fm25w256.h" |
elmicro | 0:2290931492e7 | 2 | #include "mbed.h" |
elmicro | 0:2290931492e7 | 3 | |
elmicro | 0:2290931492e7 | 4 | /* =================================================================== |
elmicro | 0:2290931492e7 | 5 | routine: FM25W_SSP1_Init |
elmicro | 0:2290931492e7 | 6 | purpose: Configures the LPC1768's SSP1 peripheral for |
elmicro | 0:2290931492e7 | 7 | communication with Ramtron FM25W256 FRAM memory |
elmicro | 0:2290931492e7 | 8 | parameters: none |
elmicro | 0:2290931492e7 | 9 | returns: nothing |
elmicro | 0:2290931492e7 | 10 | date: 2012-04-05 |
elmicro | 0:2290931492e7 | 11 | author: Stefan Guenther |
elmicro | 0:2290931492e7 | 12 | |
elmicro | 0:2290931492e7 | 13 | * hardware connection scheme: * |
elmicro | 0:2290931492e7 | 14 | |
elmicro | 0:2290931492e7 | 15 | mbed FRAM |
elmicro | 0:2290931492e7 | 16 | (LPC1768) |
elmicro | 0:2290931492e7 | 17 | --------+ +--------- |
elmicro | 0:2290931492e7 | 18 | | +Vcc _____ | |
elmicro | 0:2290931492e7 | 19 | | o +-----| 4k7 |---------+ !WP |
elmicro | 0:2290931492e7 | 20 | | | | | |
elmicro | 0:2290931492e7 | 21 | VCC +------+------+ | |
elmicro | 0:2290931492e7 | 22 | | | _____ | |
elmicro | 0:2290931492e7 | 23 | | +-----| 4k7 |-------- + !HOLD |
elmicro | 0:2290931492e7 | 24 | | <CLK> | |
elmicro | 0:2290931492e7 | 25 | P0.7 +--->--------------------------->---+ SCK |
elmicro | 0:2290931492e7 | 26 | | <MISO> | |
elmicro | 0:2290931492e7 | 27 | P0.8 +---<---------------------------<---+ SO |
elmicro | 0:2290931492e7 | 28 | | <MOSI> | |
elmicro | 0:2290931492e7 | 29 | P0.9 +--->--------------------------->---+ SI |
elmicro | 0:2290931492e7 | 30 | | <!SSL> | |
elmicro | 0:2290931492e7 | 31 | P0.6 +--->--------------------------->---+ !CS |
elmicro | 0:2290931492e7 | 32 | | | |
elmicro | 0:2290931492e7 | 33 | GND +------------------+----------------+ GND |
elmicro | 0:2290931492e7 | 34 | | | | |
elmicro | 0:2290931492e7 | 35 | --------+ o +--------- |
elmicro | 0:2290931492e7 | 36 | 0V |
elmicro | 0:2290931492e7 | 37 | Keep traces as short as possible - SPI frequency is 10MHz! |
elmicro | 0:2290931492e7 | 38 | -------------------------------------------------------------------*/ |
elmicro | 0:2290931492e7 | 39 | void FM25W_SSP1_Init(void) |
elmicro | 0:2290931492e7 | 40 | { |
elmicro | 0:2290931492e7 | 41 | LPC_SC->PCLKSEL0|=(1<<20); //SSP clock = 1x System Clock |
elmicro | 0:2290931492e7 | 42 | LPC_SC->PCONP |= BIT10; //enable power to SSP1 peripheral |
elmicro | 0:2290931492e7 | 43 | //P0.6 -> SSEL |
elmicro | 0:2290931492e7 | 44 | //P0.7 -> SCK |
elmicro | 0:2290931492e7 | 45 | //P0.8 -> MISO |
elmicro | 0:2290931492e7 | 46 | //P0.9 -> MOSI |
elmicro | 0:2290931492e7 | 47 | LPC_PINCON->PINSEL0 &=~0xFC000; //reset GPIO functions for needed portpins |
elmicro | 0:2290931492e7 | 48 | LPC_PINCON->PINSEL0 |= 0xA8000; //set GPIO functions to SSP1 |
elmicro | 0:2290931492e7 | 49 | LPC_SSP1->CPSR=11; //SSP clock divider (results in 10MHz SPI Clk) |
elmicro | 0:2290931492e7 | 50 | LPC_SSP1->CR0=7;//|0x80|0x40; //FRF=SPI, DSS=8, SPO=1, SPH=1 |
elmicro | 0:2290931492e7 | 51 | LPC_SSP1->CR1 &=~BIT2; //SSP1 is master |
elmicro | 0:2290931492e7 | 52 | LPC_SSP1->CR1 |= BIT1; //enable SSP1 peripheral (SSE bit) |
elmicro | 0:2290931492e7 | 53 | LPC_PINCON->PINSEL0 &=~0x3000; //p8 [P0.6] is Slave Select (software driven) |
elmicro | 0:2290931492e7 | 54 | LPC_GPIO0->FIODIR |= BIT6; //P0.6 is output |
elmicro | 0:2290931492e7 | 55 | SSL1; |
elmicro | 0:2290931492e7 | 56 | } |
elmicro | 0:2290931492e7 | 57 | |
elmicro | 0:2290931492e7 | 58 | |
elmicro | 0:2290931492e7 | 59 | /* =================================================================== |
elmicro | 0:2290931492e7 | 60 | routine: FM25W_ReadByte |
elmicro | 0:2290931492e7 | 61 | purpose: Reads a single byte from specified memory address |
elmicro | 0:2290931492e7 | 62 | parameters: <iAddress> Memory address to read |
elmicro | 0:2290931492e7 | 63 | returns: Memory content |
elmicro | 0:2290931492e7 | 64 | date: 2012-04-05 |
elmicro | 0:2290931492e7 | 65 | author: Stefan Guenther |
elmicro | 0:2290931492e7 | 66 | -------------------------------------------------------------------*/ |
elmicro | 0:2290931492e7 | 67 | unsigned char FM25W_ReadByte(unsigned int iAddress) |
elmicro | 0:2290931492e7 | 68 | { |
elmicro | 0:2290931492e7 | 69 | unsigned char retVal=0; |
elmicro | 0:2290931492e7 | 70 | while(!(LPC_SSP1->SR&BIT0)); //wait for TX FIFO to get empty |
elmicro | 0:2290931492e7 | 71 | SSL0; |
elmicro | 0:2290931492e7 | 72 | LPC_SSP1->DR = READ; |
elmicro | 0:2290931492e7 | 73 | LPC_SSP1->DR = (iAddress >> 8) & 0xFF; //Send top address byte to read from |
elmicro | 0:2290931492e7 | 74 | LPC_SSP1->DR = iAddress & 0xFF; //Send Middle address byte to read from |
elmicro | 0:2290931492e7 | 75 | LPC_SSP1->DR = 0; |
elmicro | 0:2290931492e7 | 76 | while(LPC_SSP1->SR&BIT4); //wait for TX to end |
elmicro | 0:2290931492e7 | 77 | while(LPC_SSP1->SR&BIT2) //read out RX FIFO |
elmicro | 0:2290931492e7 | 78 | retVal = LPC_SSP1->DR; //last FIFO entry is our data byte |
elmicro | 0:2290931492e7 | 79 | SSL1; |
elmicro | 0:2290931492e7 | 80 | return(retVal); |
elmicro | 0:2290931492e7 | 81 | } |
elmicro | 0:2290931492e7 | 82 | |
elmicro | 0:2290931492e7 | 83 | /* =================================================================== |
elmicro | 0:2290931492e7 | 84 | routine: FM25W_WriteByte |
elmicro | 0:2290931492e7 | 85 | purpose: Writes a single byte to specified memory address |
elmicro | 0:2290931492e7 | 86 | parameters: <iAddress> Memory address to write to |
elmicro | 0:2290931492e7 | 87 | <cByte> Data to be written |
elmicro | 0:2290931492e7 | 88 | returns: nothing |
elmicro | 0:2290931492e7 | 89 | date: 2012-04-05 |
elmicro | 0:2290931492e7 | 90 | author: Stefan Guenther |
elmicro | 0:2290931492e7 | 91 | -------------------------------------------------------------------*/ |
elmicro | 0:2290931492e7 | 92 | void FM25W_WriteByte(unsigned int iAddress, unsigned char cByte) |
elmicro | 0:2290931492e7 | 93 | { |
elmicro | 0:2290931492e7 | 94 | while(!(LPC_SSP1->SR&BIT0)); //wait for TX FIFO to get empty |
elmicro | 0:2290931492e7 | 95 | SSL0; |
elmicro | 0:2290931492e7 | 96 | LPC_SSP1->DR = WREN; //WREN has to be written prior to |
elmicro | 0:2290931492e7 | 97 | //each write access to FRAM |
elmicro | 0:2290931492e7 | 98 | while(LPC_SSP1->SR&BIT4); //wait for TX to end |
elmicro | 0:2290931492e7 | 99 | SSL1; |
elmicro | 0:2290931492e7 | 100 | while(LPC_SSP1->SR&BIT2) //clear RX FIFO |
elmicro | 0:2290931492e7 | 101 | if(LPC_SSP1->DR); |
elmicro | 0:2290931492e7 | 102 | SSL0; |
elmicro | 0:2290931492e7 | 103 | LPC_SSP1->DR = WRITE; |
elmicro | 0:2290931492e7 | 104 | LPC_SSP1->DR = (iAddress >> 8) & 0xFF; //Send top address byte to read from |
elmicro | 0:2290931492e7 | 105 | LPC_SSP1->DR = iAddress & 0xFF; //Send low address byte to read from |
elmicro | 0:2290931492e7 | 106 | LPC_SSP1->DR = cByte; |
elmicro | 0:2290931492e7 | 107 | while(LPC_SSP1->SR&BIT4); //wait for TX to end |
elmicro | 0:2290931492e7 | 108 | while(LPC_SSP1->SR&BIT2) //clear RX FIFO |
elmicro | 0:2290931492e7 | 109 | if(LPC_SSP1->DR); |
elmicro | 0:2290931492e7 | 110 | SSL1; |
elmicro | 0:2290931492e7 | 111 | } |
elmicro | 0:2290931492e7 | 112 | |
elmicro | 0:2290931492e7 | 113 | /* =================================================================== |
elmicro | 0:2290931492e7 | 114 | routine: FM25W_WriteBlock |
elmicro | 0:2290931492e7 | 115 | purpose: Writes a block of data, starting at specified |
elmicro | 0:2290931492e7 | 116 | memory address |
elmicro | 0:2290931492e7 | 117 | parameters: <iAddress> First memory address to be written |
elmicro | 0:2290931492e7 | 118 | <*ptrBlock> Pointer to data block to be written |
elmicro | 0:2290931492e7 | 119 | <iCount> Length (in bytes) of data block |
elmicro | 0:2290931492e7 | 120 | returns: nothing |
elmicro | 0:2290931492e7 | 121 | date: 2012-04-05 |
elmicro | 0:2290931492e7 | 122 | author: Stefan Guenther |
elmicro | 0:2290931492e7 | 123 | -------------------------------------------------------------------*/ |
elmicro | 0:2290931492e7 | 124 | void FM25W_WriteBlock(unsigned int iAddress, unsigned char *ptrBlock, unsigned int iCount) |
elmicro | 0:2290931492e7 | 125 | { |
elmicro | 0:2290931492e7 | 126 | int x; |
elmicro | 0:2290931492e7 | 127 | while(!(LPC_SSP1->SR&BIT0)); //wait for TX FIFO to get empty |
elmicro | 0:2290931492e7 | 128 | SSL0; |
elmicro | 0:2290931492e7 | 129 | LPC_SSP1->DR = WREN; //unlock FRAM for writing |
elmicro | 0:2290931492e7 | 130 | while(LPC_SSP1->SR&BIT4); //wait for TX to end |
elmicro | 0:2290931492e7 | 131 | SSL1; |
elmicro | 0:2290931492e7 | 132 | while(LPC_SSP1->SR&BIT2) //clear RX FIFO |
elmicro | 0:2290931492e7 | 133 | if(LPC_SSP1->DR); |
elmicro | 0:2290931492e7 | 134 | SSL0; |
elmicro | 0:2290931492e7 | 135 | LPC_SSP1->DR = WRITE; //send write command |
elmicro | 0:2290931492e7 | 136 | LPC_SSP1->DR = (iAddress >> 8) & 0xFF; //set start adress of block |
elmicro | 0:2290931492e7 | 137 | LPC_SSP1->DR = iAddress & 0xFF; |
elmicro | 0:2290931492e7 | 138 | for(x=0; x<iCount; x++) |
elmicro | 0:2290931492e7 | 139 | { |
elmicro | 0:2290931492e7 | 140 | while(!(LPC_SSP1->SR&BIT1)); //wait as TX FIFO is full |
elmicro | 0:2290931492e7 | 141 | |
elmicro | 0:2290931492e7 | 142 | LPC_SSP1->DR = *ptrBlock; |
elmicro | 0:2290931492e7 | 143 | ptrBlock++; |
elmicro | 0:2290931492e7 | 144 | } |
elmicro | 0:2290931492e7 | 145 | while(LPC_SSP1->SR&BIT4); //wait for TX to end |
elmicro | 0:2290931492e7 | 146 | SSL1; |
elmicro | 0:2290931492e7 | 147 | while(LPC_SSP1->SR&BIT2) //clear RX FIFO |
elmicro | 0:2290931492e7 | 148 | if(LPC_SSP1->DR); |
elmicro | 0:2290931492e7 | 149 | } |
elmicro | 0:2290931492e7 | 150 | |
elmicro | 0:2290931492e7 | 151 | /* =================================================================== |
elmicro | 0:2290931492e7 | 152 | routine: FM25W_ReadBlock |
elmicro | 0:2290931492e7 | 153 | purpose: Reads a block of data, starting at specified |
elmicro | 0:2290931492e7 | 154 | memory address |
elmicro | 0:2290931492e7 | 155 | parameters: <iAddress> First memory address to be read |
elmicro | 0:2290931492e7 | 156 | <*ptrBlock> Pointer to local RAM for data block |
elmicro | 0:2290931492e7 | 157 | <iCount> Length (in bytes) of data block to read |
elmicro | 0:2290931492e7 | 158 | returns: nothing |
elmicro | 0:2290931492e7 | 159 | date: 2012-04-05 |
elmicro | 0:2290931492e7 | 160 | author: Stefan Guenther |
elmicro | 0:2290931492e7 | 161 | -------------------------------------------------------------------*/ |
elmicro | 0:2290931492e7 | 162 | void FM25W_ReadBlock(unsigned int iAddress, unsigned char *ptrBlock, unsigned int iCount) |
elmicro | 0:2290931492e7 | 163 | { |
elmicro | 0:2290931492e7 | 164 | int x; |
elmicro | 0:2290931492e7 | 165 | |
elmicro | 0:2290931492e7 | 166 | while(LPC_SSP1->SR&BIT2) //clear RX FIFO |
elmicro | 0:2290931492e7 | 167 | if(LPC_SSP1->DR); |
elmicro | 0:2290931492e7 | 168 | while(!(LPC_SSP1->SR&BIT0)); //wait for TX FIFO to get empty |
elmicro | 0:2290931492e7 | 169 | |
elmicro | 0:2290931492e7 | 170 | SSL0; |
elmicro | 0:2290931492e7 | 171 | |
elmicro | 0:2290931492e7 | 172 | LPC_SSP1->DR = READ; |
elmicro | 0:2290931492e7 | 173 | LPC_SSP1->DR = (iAddress >> 8) & 0xFF; //send upper address byte to read from |
elmicro | 0:2290931492e7 | 174 | LPC_SSP1->DR = iAddress & 0xFF; //send lower address byte to read from |
elmicro | 0:2290931492e7 | 175 | while(LPC_SSP1->SR&BIT4); //wait for TX FIFO to get empty |
elmicro | 0:2290931492e7 | 176 | x = LPC_SSP1->DR; //clear RX FIFO |
elmicro | 0:2290931492e7 | 177 | x = LPC_SSP1->DR; |
elmicro | 0:2290931492e7 | 178 | x = LPC_SSP1->DR; |
elmicro | 0:2290931492e7 | 179 | |
elmicro | 0:2290931492e7 | 180 | for(x=0; x<iCount; x++) |
elmicro | 0:2290931492e7 | 181 | { |
elmicro | 0:2290931492e7 | 182 | LPC_SSP1->DR = 0; //send first dummy byte |
elmicro | 0:2290931492e7 | 183 | while(LPC_SSP1->SR&BIT4); //wait for TX FIFO to get empty |
elmicro | 0:2290931492e7 | 184 | *ptrBlock = LPC_SSP1->DR; //last FIFO entry is our data byte |
elmicro | 0:2290931492e7 | 185 | ptrBlock++; |
elmicro | 0:2290931492e7 | 186 | } |
elmicro | 0:2290931492e7 | 187 | SSL1; |
elmicro | 0:2290931492e7 | 188 | while(LPC_SSP1->SR&BIT2) //clear RX FIFO |
elmicro | 0:2290931492e7 | 189 | if(LPC_SSP1->DR); |
elmicro | 0:2290931492e7 | 190 | } |
elmicro | 0:2290931492e7 | 191 |