A library for using FeRAM from Ramtron
FeRAM.cpp@0:f93930fa4df5, 2012-01-19 (annotated)
- Committer:
- ms523
- Date:
- Thu Jan 19 16:51:29 2012 +0000
- Revision:
- 0:f93930fa4df5
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ms523 | 0:f93930fa4df5 | 1 | #include "mbed.h" |
ms523 | 0:f93930fa4df5 | 2 | #include "FeRAM.h" |
ms523 | 0:f93930fa4df5 | 3 | |
ms523 | 0:f93930fa4df5 | 4 | FeRAM::FeRAM(PinName mosi, PinName miso, PinName sclk) : _spi(mosi, miso, sclk) { |
ms523 | 0:f93930fa4df5 | 5 | |
ms523 | 0:f93930fa4df5 | 6 | _miso = miso; // To see which port was used |
ms523 | 0:f93930fa4df5 | 7 | |
ms523 | 0:f93930fa4df5 | 8 | // Set up the SPI port... |
ms523 | 0:f93930fa4df5 | 9 | _spi.frequency(32000000); // 32MHz is the fastest mbed frequency supported by the FeRAM |
ms523 | 0:f93930fa4df5 | 10 | _spi.format(8,3); // Set for mode 3 |
ms523 | 0:f93930fa4df5 | 11 | if (_miso == p6) { |
ms523 | 0:f93930fa4df5 | 12 | LPC_PINCON->PINSEL0 |= p6_SSEL; // Set up SSEL1 |
ms523 | 0:f93930fa4df5 | 13 | } else if (_miso == p12) { |
ms523 | 0:f93930fa4df5 | 14 | LPC_PINCON->PINSEL1 |= p14_SSEL;// Set up SSEL1 |
ms523 | 0:f93930fa4df5 | 15 | } |
ms523 | 0:f93930fa4df5 | 16 | |
ms523 | 0:f93930fa4df5 | 17 | // To start with I need the chip select high and wait 1ms after powering up |
ms523 | 0:f93930fa4df5 | 18 | wait(0.001); // Must wait 1ms after power on before using FeRAM |
ms523 | 0:f93930fa4df5 | 19 | } |
ms523 | 0:f93930fa4df5 | 20 | |
ms523 | 0:f93930fa4df5 | 21 | /*** My method to write to FeRAM ***/ |
ms523 | 0:f93930fa4df5 | 22 | void FeRAM::spi_write_SSP1 (unsigned char data) { |
ms523 | 0:f93930fa4df5 | 23 | // First don't write to the FIFO buffer if it is full |
ms523 | 0:f93930fa4df5 | 24 | while (!(LPC_SSP1->SR & TNF)) // While TNF-Bit = 0 (FIFO full)... |
ms523 | 0:f93930fa4df5 | 25 | ; // Wait |
ms523 | 0:f93930fa4df5 | 26 | LPC_SSP1->DR = data; // Write to FIFO buffer |
ms523 | 0:f93930fa4df5 | 27 | } |
ms523 | 0:f93930fa4df5 | 28 | |
ms523 | 0:f93930fa4df5 | 29 | void FeRAM::spi_write_SSP0 (unsigned char data) { |
ms523 | 0:f93930fa4df5 | 30 | // First don't write to the FIFO buffer if it is full |
ms523 | 0:f93930fa4df5 | 31 | while (!(LPC_SSP0->SR & TNF)) // While TNF-Bit = 0 (FIFO full)... |
ms523 | 0:f93930fa4df5 | 32 | ; // Wait |
ms523 | 0:f93930fa4df5 | 33 | LPC_SSP0->DR = data; // Write to FIFO buffer |
ms523 | 0:f93930fa4df5 | 34 | } |
ms523 | 0:f93930fa4df5 | 35 | |
ms523 | 0:f93930fa4df5 | 36 | /*** Write a byte to FeRAM ***/ |
ms523 | 0:f93930fa4df5 | 37 | void FeRAM::write_byte (int address, unsigned char data) { |
ms523 | 0:f93930fa4df5 | 38 | if (_miso == p6) { |
ms523 | 0:f93930fa4df5 | 39 | spi_write_SSP1(WREN); // Send the write enable command |
ms523 | 0:f93930fa4df5 | 40 | while (!(LPC_SSP1->SR & TFE)) // While TFE-Bit = 1 (FIFO empty)... |
ms523 | 0:f93930fa4df5 | 41 | ; // Wait |
ms523 | 0:f93930fa4df5 | 42 | spi_write_SSP1(WRITE); // Send write command |
ms523 | 0:f93930fa4df5 | 43 | spi_write_SSP1(address >> 16); // Send top address byte to write to |
ms523 | 0:f93930fa4df5 | 44 | spi_write_SSP1((address >> 8) & 0xFF); // Send Middle address byte to write to |
ms523 | 0:f93930fa4df5 | 45 | spi_write_SSP1(address & 0xFF); // Send Bottom address byte to write to |
ms523 | 0:f93930fa4df5 | 46 | spi_write_SSP1(data); // Send data to be writen |
ms523 | 0:f93930fa4df5 | 47 | // Now I need to check that the FIFO transmit buffer is empty exiting the method |
ms523 | 0:f93930fa4df5 | 48 | while (!(LPC_SSP1->SR & TFE)) // While TFE-Bit = 0 (FIFO not empty)... |
ms523 | 0:f93930fa4df5 | 49 | ; // Wait |
ms523 | 0:f93930fa4df5 | 50 | } else if (_miso == p12) { |
ms523 | 0:f93930fa4df5 | 51 | spi_write_SSP0(WREN); // Send the write enable command |
ms523 | 0:f93930fa4df5 | 52 | while (!(LPC_SSP0->SR & TFE)) // While TFE-Bit = 1 (FIFO empty)... |
ms523 | 0:f93930fa4df5 | 53 | ; // Wait |
ms523 | 0:f93930fa4df5 | 54 | spi_write_SSP0(WRITE); // Send write command |
ms523 | 0:f93930fa4df5 | 55 | spi_write_SSP0(address >> 16); // Send top address byte to write to |
ms523 | 0:f93930fa4df5 | 56 | spi_write_SSP0((address >> 8) & 0xFF); // Send Middle address byte to write to |
ms523 | 0:f93930fa4df5 | 57 | spi_write_SSP0(address & 0xFF); // Send Bottom address byte to write to |
ms523 | 0:f93930fa4df5 | 58 | spi_write_SSP0(data); // Send data to be writen |
ms523 | 0:f93930fa4df5 | 59 | // Now I need to check that the FIFO transmit buffer is empty exiting the method |
ms523 | 0:f93930fa4df5 | 60 | while (!(LPC_SSP0->SR & TFE)) // While TFE-Bit = 0 (FIFO not empty)... |
ms523 | 0:f93930fa4df5 | 61 | ; // Wait |
ms523 | 0:f93930fa4df5 | 62 | } |
ms523 | 0:f93930fa4df5 | 63 | } |
ms523 | 0:f93930fa4df5 | 64 | |
ms523 | 0:f93930fa4df5 | 65 | /*** Read a byte from FeRAM ***/ |
ms523 | 0:f93930fa4df5 | 66 | unsigned char FeRAM::read_byte (int address) { |
ms523 | 0:f93930fa4df5 | 67 | unsigned char my_val; // Variable to store the read data |
ms523 | 0:f93930fa4df5 | 68 | if (_miso == p6) { |
ms523 | 0:f93930fa4df5 | 69 | spi_write_SSP1(READ); // Send read command |
ms523 | 0:f93930fa4df5 | 70 | spi_write_SSP1(address >> 16); // Send top address byte to read from |
ms523 | 0:f93930fa4df5 | 71 | spi_write_SSP1((address >> 8) & 0xFF); // Send Middle address byte to read from |
ms523 | 0:f93930fa4df5 | 72 | spi_write_SSP1(address & 0xFF); // Send Bottom address byte to read from |
ms523 | 0:f93930fa4df5 | 73 | // Now the buffer is empty send out a dummy byte and read the buffer |
ms523 | 0:f93930fa4df5 | 74 | spi_write_SSP1(0x00); // Send the dummy byte |
ms523 | 0:f93930fa4df5 | 75 | // Now I need to empty the FIFO receive buffer... |
ms523 | 0:f93930fa4df5 | 76 | while (LPC_SSP1->SR & RNE) // While RNE-Bit = 1 (FIFO receive buffer not empty)... |
ms523 | 0:f93930fa4df5 | 77 | my_val = LPC_SSP1->DR; // Read the byte in the buffer |
ms523 | 0:f93930fa4df5 | 78 | } else if (_miso == p12) { |
ms523 | 0:f93930fa4df5 | 79 | spi_write_SSP0(READ); // Send read command |
ms523 | 0:f93930fa4df5 | 80 | spi_write_SSP0(address >> 16); // Send top address byte to read from |
ms523 | 0:f93930fa4df5 | 81 | spi_write_SSP0((address >> 8) & 0xFF); // Send Middle address byte to read from |
ms523 | 0:f93930fa4df5 | 82 | spi_write_SSP0(address & 0xFF); // Send Bottom address byte to read from |
ms523 | 0:f93930fa4df5 | 83 | // Now the buffer is empty send out a dummy byte and read the buffer |
ms523 | 0:f93930fa4df5 | 84 | spi_write_SSP0(0x00); // Send the dummy byte |
ms523 | 0:f93930fa4df5 | 85 | // Now I need to empty the FIFO receive buffer... |
ms523 | 0:f93930fa4df5 | 86 | while (LPC_SSP0->SR & RNE) // While RNE-Bit = 1 (FIFO receive buffer not empty)... |
ms523 | 0:f93930fa4df5 | 87 | my_val = LPC_SSP0->DR; // Read the byte in the buffer |
ms523 | 0:f93930fa4df5 | 88 | } |
ms523 | 0:f93930fa4df5 | 89 | return (my_val); // Return the last byte read |
ms523 | 0:f93930fa4df5 | 90 | } |
ms523 | 0:f93930fa4df5 | 91 | |
ms523 | 0:f93930fa4df5 | 92 | /*** Write a an array of bytes to FeRAM ***/ |
ms523 | 0:f93930fa4df5 | 93 | void FeRAM::write_multiple_bytes (int start_address, unsigned char* data, int length) { |
ms523 | 0:f93930fa4df5 | 94 | if (_miso == p6) { |
ms523 | 0:f93930fa4df5 | 95 | spi_write_SSP1(WREN); // Send the write enable command |
ms523 | 0:f93930fa4df5 | 96 | while (!(LPC_SSP1->SR & TFE)) // While TFE-Bit = 1 (FIFO empty)... |
ms523 | 0:f93930fa4df5 | 97 | ; // Wait |
ms523 | 0:f93930fa4df5 | 98 | spi_write_SSP1(WRITE); // Send write command |
ms523 | 0:f93930fa4df5 | 99 | spi_write_SSP1(start_address >> 16); // Send top address byte to write to |
ms523 | 0:f93930fa4df5 | 100 | spi_write_SSP1((start_address >>8)&0xFF); // Send Middle address byte to write to |
ms523 | 0:f93930fa4df5 | 101 | spi_write_SSP1(start_address & 0xFF); // Send Bottom address byte to write to |
ms523 | 0:f93930fa4df5 | 102 | // Now I can start writing the data |
ms523 | 0:f93930fa4df5 | 103 | for (int i = 0; i < length; i++) { |
ms523 | 0:f93930fa4df5 | 104 | spi_write_SSP1(data[i]); // Send the next byte to be writen |
ms523 | 0:f93930fa4df5 | 105 | } |
ms523 | 0:f93930fa4df5 | 106 | // Now I need to check that the FIFO transmit buffer is empty exiting the method |
ms523 | 0:f93930fa4df5 | 107 | while (!(LPC_SSP1->SR & TFE)) // While TFE-Bit = 0 (FIFO not empty)... |
ms523 | 0:f93930fa4df5 | 108 | ; // Wait |
ms523 | 0:f93930fa4df5 | 109 | } else if (_miso == p12) { |
ms523 | 0:f93930fa4df5 | 110 | spi_write_SSP0(WREN); // Send the write enable command |
ms523 | 0:f93930fa4df5 | 111 | while (!(LPC_SSP0->SR & TFE)) // While TFE-Bit = 1 (FIFO empty)... |
ms523 | 0:f93930fa4df5 | 112 | ; // Wait |
ms523 | 0:f93930fa4df5 | 113 | spi_write_SSP0(WRITE); // Send write command |
ms523 | 0:f93930fa4df5 | 114 | spi_write_SSP0(start_address >> 16); // Send top address byte to write to |
ms523 | 0:f93930fa4df5 | 115 | spi_write_SSP0((start_address >>8)&0xFF); // Send Middle address byte to write to |
ms523 | 0:f93930fa4df5 | 116 | spi_write_SSP0(start_address & 0xFF); // Send Bottom address byte to write to |
ms523 | 0:f93930fa4df5 | 117 | // Now I can start writing the data |
ms523 | 0:f93930fa4df5 | 118 | for (int i = 0; i < length; i++) { |
ms523 | 0:f93930fa4df5 | 119 | spi_write_SSP0(data[i]); // Send the next byte to be writen |
ms523 | 0:f93930fa4df5 | 120 | } |
ms523 | 0:f93930fa4df5 | 121 | // Now I need to check that the FIFO transmit buffer is empty exiting the method |
ms523 | 0:f93930fa4df5 | 122 | while (!(LPC_SSP0->SR & TFE)) // While TFE-Bit = 0 (FIFO not empty)... |
ms523 | 0:f93930fa4df5 | 123 | ; // Wait |
ms523 | 0:f93930fa4df5 | 124 | } |
ms523 | 0:f93930fa4df5 | 125 | } |
ms523 | 0:f93930fa4df5 | 126 | |
ms523 | 0:f93930fa4df5 | 127 | /*** Read multiple bytes from FeRAM and store in an array***/ |
ms523 | 0:f93930fa4df5 | 128 | void FeRAM::read_multiple_bytes (int start_address, unsigned char* data, int length) { |
ms523 | 0:f93930fa4df5 | 129 | if (_miso == p6) { |
ms523 | 0:f93930fa4df5 | 130 | // First configure the SSEL to cs and pull low to start read |
ms523 | 0:f93930fa4df5 | 131 | LPC_PINCON->PINSEL0 &= p6_GPIO; // Clear bit to set up p0.6 as GPIO |
ms523 | 0:f93930fa4df5 | 132 | LPC_GPIO0->FIODIR |= (1 << 6); // Config as output |
ms523 | 0:f93930fa4df5 | 133 | LPC_GPIO0->FIOCLR = (1 << 6); // Set bit to set output logic low |
ms523 | 0:f93930fa4df5 | 134 | // Now pin is set read the data |
ms523 | 0:f93930fa4df5 | 135 | spi_write_SSP1(READ); // Send read command |
ms523 | 0:f93930fa4df5 | 136 | spi_write_SSP1(start_address >> 16); // Send top address byte to read from |
ms523 | 0:f93930fa4df5 | 137 | spi_write_SSP1((start_address >>8)&0xFF); // Send Middle address byte to read from |
ms523 | 0:f93930fa4df5 | 138 | spi_write_SSP1(start_address & 0xFF); // Send Bottom address byte to read from |
ms523 | 0:f93930fa4df5 | 139 | spi_write_SSP1(0x00); // Write dummy byte |
ms523 | 0:f93930fa4df5 | 140 | // Now I can start reading the data |
ms523 | 0:f93930fa4df5 | 141 | for (int i = 0; i < length; i++) { |
ms523 | 0:f93930fa4df5 | 142 | spi_write_SSP1(0x00); // Write dummy byte |
ms523 | 0:f93930fa4df5 | 143 | while (LPC_SSP1->SR & RNE) // While RNE-Bit = 1 (FIFO receive buffer not empty)... |
ms523 | 0:f93930fa4df5 | 144 | data[i] = LPC_SSP1->DR; // Read the byte in the buffer |
ms523 | 0:f93930fa4df5 | 145 | } |
ms523 | 0:f93930fa4df5 | 146 | LPC_GPIO0->FIOSET = (1 << 6); // Set bit to set output logic high |
ms523 | 0:f93930fa4df5 | 147 | LPC_PINCON->PINSEL0 |= p6_SSEL; // Clear bit to set up p0.6 as GPIO |
ms523 | 0:f93930fa4df5 | 148 | } else if (_miso == p12) { |
ms523 | 0:f93930fa4df5 | 149 | LPC_PINCON->PINSEL1 &= p14_GPIO; // Clear bit to set up p0.16 as GPIO |
ms523 | 0:f93930fa4df5 | 150 | LPC_GPIO0->FIODIR |= (1 << 16); // Config as output |
ms523 | 0:f93930fa4df5 | 151 | LPC_GPIO0->FIOCLR = (1 << 16); // Set bit to set output logic low |
ms523 | 0:f93930fa4df5 | 152 | // Now pin is set read the data |
ms523 | 0:f93930fa4df5 | 153 | spi_write_SSP0(READ); // Send read command |
ms523 | 0:f93930fa4df5 | 154 | spi_write_SSP0(start_address >> 16); // Send top address byte to read from |
ms523 | 0:f93930fa4df5 | 155 | spi_write_SSP0((start_address >>8)&0xFF); // Send Middle address byte to read from |
ms523 | 0:f93930fa4df5 | 156 | spi_write_SSP0(start_address & 0xFF); // Send Bottom address byte to read from |
ms523 | 0:f93930fa4df5 | 157 | spi_write_SSP0(0x00); // Write dummy byte |
ms523 | 0:f93930fa4df5 | 158 | // Now I can start reading the data |
ms523 | 0:f93930fa4df5 | 159 | for (int i = 0; i < length; i++) { |
ms523 | 0:f93930fa4df5 | 160 | spi_write_SSP0(0x00); // Write dummy byte |
ms523 | 0:f93930fa4df5 | 161 | while (LPC_SSP0->SR & RNE) // While RNE-Bit = 1 (FIFO receive buffer not empty)... |
ms523 | 0:f93930fa4df5 | 162 | data[i] = LPC_SSP0->DR; // Read the byte in the buffer |
ms523 | 0:f93930fa4df5 | 163 | } |
ms523 | 0:f93930fa4df5 | 164 | LPC_GPIO0->FIOSET = (1 << 16); // Set bit to set output logic high |
ms523 | 0:f93930fa4df5 | 165 | LPC_PINCON->PINSEL1 |= p14_SSEL; // Clear bit to set up p0.16 as GPIO |
ms523 | 0:f93930fa4df5 | 166 | } |
ms523 | 0:f93930fa4df5 | 167 | data[0] = read_byte (start_address); |
ms523 | 0:f93930fa4df5 | 168 | data[1] = read_byte (start_address+1); |
ms523 | 0:f93930fa4df5 | 169 | } |