Version for FWST0001_v2_00
Fork of 25LCxxx_SPI by
Ser25lcxxx.cpp@0:238ca4fdef8c, 2011-01-26 (annotated)
- Committer:
- hlipka
- Date:
- Wed Jan 26 22:14:41 2011 +0000
- Revision:
- 0:238ca4fdef8c
- Child:
- 1:c29a67c7034d
initial version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hlipka | 0:238ca4fdef8c | 1 | #include "Ser25lcxxx.h" |
hlipka | 0:238ca4fdef8c | 2 | #include "wait_api.h" |
hlipka | 0:238ca4fdef8c | 3 | |
hlipka | 0:238ca4fdef8c | 4 | #define HIGH(x) ((x&0xff00)>>8) |
hlipka | 0:238ca4fdef8c | 5 | #define LOW(x) (x&0xff) |
hlipka | 0:238ca4fdef8c | 6 | |
hlipka | 0:238ca4fdef8c | 7 | Ser25LCxxx::Ser25LCxxx(SPI *spi, PinName enable, int bytes, int pagesize) { |
hlipka | 0:238ca4fdef8c | 8 | _spi=spi; |
hlipka | 0:238ca4fdef8c | 9 | _enable=new DigitalOut(enable); |
hlipka | 0:238ca4fdef8c | 10 | _size=bytes; |
hlipka | 0:238ca4fdef8c | 11 | _pageSize=pagesize; |
hlipka | 0:238ca4fdef8c | 12 | _enable->write(1); |
hlipka | 0:238ca4fdef8c | 13 | } |
hlipka | 0:238ca4fdef8c | 14 | |
hlipka | 0:238ca4fdef8c | 15 | Ser25LCxxx::~Ser25LCxxx() { |
hlipka | 0:238ca4fdef8c | 16 | delete _enable; |
hlipka | 0:238ca4fdef8c | 17 | } |
hlipka | 0:238ca4fdef8c | 18 | |
hlipka | 0:238ca4fdef8c | 19 | char* Ser25LCxxx::read(unsigned int startAdr, unsigned int len) { |
hlipka | 0:238ca4fdef8c | 20 | // assertion |
hlipka | 0:238ca4fdef8c | 21 | if (startAdr+len>_size) |
hlipka | 0:238ca4fdef8c | 22 | return NULL; |
hlipka | 0:238ca4fdef8c | 23 | char* ret=(char*)malloc(len); |
hlipka | 0:238ca4fdef8c | 24 | _enable->write(0); |
hlipka | 0:238ca4fdef8c | 25 | wait_us(1); |
hlipka | 0:238ca4fdef8c | 26 | // send address |
hlipka | 0:238ca4fdef8c | 27 | if (_size<512) { // 256 and 128 bytes |
hlipka | 0:238ca4fdef8c | 28 | _spi->write(0x03); |
hlipka | 0:238ca4fdef8c | 29 | _spi->write(LOW(startAdr)); |
hlipka | 0:238ca4fdef8c | 30 | } else if (512==_size) { // 4k variant adds 9th address bit to command |
hlipka | 0:238ca4fdef8c | 31 | _spi->write(startAdr>255?0xb:0x3); |
hlipka | 0:238ca4fdef8c | 32 | _spi->write(LOW(startAdr)); |
hlipka | 0:238ca4fdef8c | 33 | } else if (_size<131072) { // everything up to 512k |
hlipka | 0:238ca4fdef8c | 34 | _spi->write(0x03); |
hlipka | 0:238ca4fdef8c | 35 | _spi->write(HIGH(startAdr)); |
hlipka | 0:238ca4fdef8c | 36 | _spi->write(LOW(startAdr)); |
hlipka | 0:238ca4fdef8c | 37 | } else { // 25xx1024, needs 3 byte address |
hlipka | 0:238ca4fdef8c | 38 | _spi->write(0x03); |
hlipka | 0:238ca4fdef8c | 39 | _spi->write(startAdr>>16); |
hlipka | 0:238ca4fdef8c | 40 | _spi->write(HIGH(startAdr)); |
hlipka | 0:238ca4fdef8c | 41 | _spi->write(LOW(startAdr)); |
hlipka | 0:238ca4fdef8c | 42 | } |
hlipka | 0:238ca4fdef8c | 43 | // read data into buffer |
hlipka | 0:238ca4fdef8c | 44 | for (int i=0;i<len;i++) { |
hlipka | 0:238ca4fdef8c | 45 | ret[i]=_spi->write(0); |
hlipka | 0:238ca4fdef8c | 46 | } |
hlipka | 0:238ca4fdef8c | 47 | wait_us(1); |
hlipka | 0:238ca4fdef8c | 48 | _enable->write(1); |
hlipka | 0:238ca4fdef8c | 49 | return ret; |
hlipka | 0:238ca4fdef8c | 50 | } |
hlipka | 0:238ca4fdef8c | 51 | |
hlipka | 0:238ca4fdef8c | 52 | bool Ser25LCxxx::write(unsigned int startAdr, unsigned int len, const char* data) { |
hlipka | 0:238ca4fdef8c | 53 | if (startAdr+len>_size) |
hlipka | 0:238ca4fdef8c | 54 | return -1; |
hlipka | 0:238ca4fdef8c | 55 | |
hlipka | 0:238ca4fdef8c | 56 | int ofs=0; |
hlipka | 0:238ca4fdef8c | 57 | while (ofs<len) { |
hlipka | 0:238ca4fdef8c | 58 | // calculate amount of data to write into current page |
hlipka | 0:238ca4fdef8c | 59 | int pageLen=_pageSize-((startAdr+ofs)%_pageSize); |
hlipka | 0:238ca4fdef8c | 60 | if (ofs+pageLen>len) |
hlipka | 0:238ca4fdef8c | 61 | pageLen=len-ofs; |
hlipka | 0:238ca4fdef8c | 62 | // write single page |
hlipka | 0:238ca4fdef8c | 63 | bool b=writePage(startAdr+ofs,pageLen,data+ofs); |
hlipka | 0:238ca4fdef8c | 64 | if (!b) |
hlipka | 0:238ca4fdef8c | 65 | return false; |
hlipka | 0:238ca4fdef8c | 66 | // and switch to next page |
hlipka | 0:238ca4fdef8c | 67 | ofs+=pageLen; |
hlipka | 0:238ca4fdef8c | 68 | } |
hlipka | 0:238ca4fdef8c | 69 | return true; |
hlipka | 0:238ca4fdef8c | 70 | } |
hlipka | 0:238ca4fdef8c | 71 | |
hlipka | 0:238ca4fdef8c | 72 | bool Ser25LCxxx::writePage(unsigned int startAdr, unsigned int len, const char* data) { |
hlipka | 0:238ca4fdef8c | 73 | enableWrite(); |
hlipka | 0:238ca4fdef8c | 74 | |
hlipka | 0:238ca4fdef8c | 75 | _enable->write(0); |
hlipka | 0:238ca4fdef8c | 76 | wait_us(1); |
hlipka | 0:238ca4fdef8c | 77 | |
hlipka | 0:238ca4fdef8c | 78 | if (_size<512) { // 256 and 128 bytes |
hlipka | 0:238ca4fdef8c | 79 | _spi->write(0x02); |
hlipka | 0:238ca4fdef8c | 80 | _spi->write(LOW(startAdr)); |
hlipka | 0:238ca4fdef8c | 81 | } else if (512==_size) { // 4k variant adds 9th address bit to command |
hlipka | 0:238ca4fdef8c | 82 | _spi->write(startAdr>255?0xa:0x2); |
hlipka | 0:238ca4fdef8c | 83 | _spi->write(LOW(startAdr)); |
hlipka | 0:238ca4fdef8c | 84 | } else if (_size<131072) { // everything up to 512k |
hlipka | 0:238ca4fdef8c | 85 | _spi->write(0x02); |
hlipka | 0:238ca4fdef8c | 86 | _spi->write(HIGH(startAdr)); |
hlipka | 0:238ca4fdef8c | 87 | _spi->write(LOW(startAdr)); |
hlipka | 0:238ca4fdef8c | 88 | } else { // 25xx1024, needs 3 byte address |
hlipka | 0:238ca4fdef8c | 89 | _spi->write(0x02); |
hlipka | 0:238ca4fdef8c | 90 | _spi->write(startAdr>>16); |
hlipka | 0:238ca4fdef8c | 91 | _spi->write(HIGH(startAdr)); |
hlipka | 0:238ca4fdef8c | 92 | _spi->write(LOW(startAdr)); |
hlipka | 0:238ca4fdef8c | 93 | } |
hlipka | 0:238ca4fdef8c | 94 | |
hlipka | 0:238ca4fdef8c | 95 | // do real write |
hlipka | 0:238ca4fdef8c | 96 | for (int i=0;i<len;i++) { |
hlipka | 0:238ca4fdef8c | 97 | _spi->write(data[i]); |
hlipka | 0:238ca4fdef8c | 98 | } |
hlipka | 0:238ca4fdef8c | 99 | wait_us(1); |
hlipka | 0:238ca4fdef8c | 100 | // disable to start physical write |
hlipka | 0:238ca4fdef8c | 101 | _enable->write(1); |
hlipka | 0:238ca4fdef8c | 102 | |
hlipka | 0:238ca4fdef8c | 103 | waitForWrite(); |
hlipka | 0:238ca4fdef8c | 104 | |
hlipka | 0:238ca4fdef8c | 105 | return true; |
hlipka | 0:238ca4fdef8c | 106 | } |
hlipka | 0:238ca4fdef8c | 107 | |
hlipka | 0:238ca4fdef8c | 108 | bool Ser25LCxxx::clearPage(unsigned int pageNum) { |
hlipka | 0:238ca4fdef8c | 109 | enableWrite(); |
hlipka | 0:238ca4fdef8c | 110 | if (_size<65535) { |
hlipka | 0:238ca4fdef8c | 111 | char* s=(char*)malloc(_pageSize); |
hlipka | 0:238ca4fdef8c | 112 | for (int i=0;i<_pageSize;i++) { |
hlipka | 0:238ca4fdef8c | 113 | s[i]=0xff; |
hlipka | 0:238ca4fdef8c | 114 | } |
hlipka | 0:238ca4fdef8c | 115 | bool b=writePage(_pageSize*pageNum,_pageSize,s); |
hlipka | 0:238ca4fdef8c | 116 | delete s; |
hlipka | 0:238ca4fdef8c | 117 | return b; |
hlipka | 0:238ca4fdef8c | 118 | } else { |
hlipka | 0:238ca4fdef8c | 119 | _enable->write(0); |
hlipka | 0:238ca4fdef8c | 120 | wait_us(1); |
hlipka | 0:238ca4fdef8c | 121 | _spi->write(0x42); |
hlipka | 0:238ca4fdef8c | 122 | _spi->write(HIGH(_pageSize*pageNum)); |
hlipka | 0:238ca4fdef8c | 123 | _spi->write(LOW(_pageSize*pageNum)); |
hlipka | 0:238ca4fdef8c | 124 | wait_us(1); |
hlipka | 0:238ca4fdef8c | 125 | _enable->write(1); |
hlipka | 0:238ca4fdef8c | 126 | |
hlipka | 0:238ca4fdef8c | 127 | waitForWrite(); |
hlipka | 0:238ca4fdef8c | 128 | } |
hlipka | 0:238ca4fdef8c | 129 | return true; |
hlipka | 0:238ca4fdef8c | 130 | } |
hlipka | 0:238ca4fdef8c | 131 | |
hlipka | 0:238ca4fdef8c | 132 | void Ser25LCxxx::clearMem() { |
hlipka | 0:238ca4fdef8c | 133 | enableWrite(); |
hlipka | 0:238ca4fdef8c | 134 | if (_size<65535) { |
hlipka | 0:238ca4fdef8c | 135 | for (int i=0;i<_size/_pageSize;i++) { |
hlipka | 0:238ca4fdef8c | 136 | if (!clearPage(i)) |
hlipka | 0:238ca4fdef8c | 137 | break; |
hlipka | 0:238ca4fdef8c | 138 | } |
hlipka | 0:238ca4fdef8c | 139 | } |
hlipka | 0:238ca4fdef8c | 140 | else |
hlipka | 0:238ca4fdef8c | 141 | { |
hlipka | 0:238ca4fdef8c | 142 | _enable->write(0); |
hlipka | 0:238ca4fdef8c | 143 | wait_us(1); |
hlipka | 0:238ca4fdef8c | 144 | _spi->write(0xc7); |
hlipka | 0:238ca4fdef8c | 145 | wait_us(1); |
hlipka | 0:238ca4fdef8c | 146 | _enable->write(1); |
hlipka | 0:238ca4fdef8c | 147 | |
hlipka | 0:238ca4fdef8c | 148 | waitForWrite(); |
hlipka | 0:238ca4fdef8c | 149 | } |
hlipka | 0:238ca4fdef8c | 150 | } |
hlipka | 0:238ca4fdef8c | 151 | |
hlipka | 0:238ca4fdef8c | 152 | int Ser25LCxxx::readStatus() { |
hlipka | 0:238ca4fdef8c | 153 | _enable->write(0); |
hlipka | 0:238ca4fdef8c | 154 | wait_us(1); |
hlipka | 0:238ca4fdef8c | 155 | _spi->write(0x5); |
hlipka | 0:238ca4fdef8c | 156 | int status=_spi->write(0x00); |
hlipka | 0:238ca4fdef8c | 157 | wait_us(1); |
hlipka | 0:238ca4fdef8c | 158 | _enable->write(1); |
hlipka | 0:238ca4fdef8c | 159 | return status; |
hlipka | 0:238ca4fdef8c | 160 | } |
hlipka | 0:238ca4fdef8c | 161 | |
hlipka | 0:238ca4fdef8c | 162 | void Ser25LCxxx::waitForWrite() { |
hlipka | 0:238ca4fdef8c | 163 | while (true) { |
hlipka | 0:238ca4fdef8c | 164 | if (0==readStatus()&1) |
hlipka | 0:238ca4fdef8c | 165 | break; |
hlipka | 0:238ca4fdef8c | 166 | wait_us(10); |
hlipka | 0:238ca4fdef8c | 167 | } |
hlipka | 0:238ca4fdef8c | 168 | } |
hlipka | 0:238ca4fdef8c | 169 | |
hlipka | 0:238ca4fdef8c | 170 | void Ser25LCxxx::enableWrite() |
hlipka | 0:238ca4fdef8c | 171 | { |
hlipka | 0:238ca4fdef8c | 172 | _enable->write(0); |
hlipka | 0:238ca4fdef8c | 173 | wait_us(1); |
hlipka | 0:238ca4fdef8c | 174 | _spi->write(0x06); |
hlipka | 0:238ca4fdef8c | 175 | wait_us(1); |
hlipka | 0:238ca4fdef8c | 176 | _enable->write(1); |
hlipka | 0:238ca4fdef8c | 177 | } |