Seiji Ainoguchi / SerialFlash

Dependents:   SerialFlashTest

Fork of SerialFlash by Seiji Ainoguchi

Committer:
s_ain
Date:
Wed Mar 02 00:28:03 2011 +0000
Revision:
1:385965a14c7c
Parent:
0:d0117f54a7ee
Child:
2:6f8ab876b516

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
s_ain 0:d0117f54a7ee 1 #include "ISPI.h"
s_ain 0:d0117f54a7ee 2 #include <string.h>
s_ain 0:d0117f54a7ee 3 #include "SST25DeviceImpl.h"
s_ain 0:d0117f54a7ee 4
s_ain 0:d0117f54a7ee 5 const SST25DeviceImpl::DeviceProperty* SST25DeviceImpl::findMatchDevice(ISPI* pSPI)
s_ain 0:d0117f54a7ee 6 {
s_ain 0:d0117f54a7ee 7 int manufacturersId;
s_ain 0:d0117f54a7ee 8 int deviceId;
s_ain 0:d0117f54a7ee 9 readId(pSPI, manufacturersId, deviceId);
s_ain 0:d0117f54a7ee 10
s_ain 0:d0117f54a7ee 11 struct SupportedDevice
s_ain 0:d0117f54a7ee 12 {
s_ain 0:d0117f54a7ee 13 int manufacturersId;
s_ain 0:d0117f54a7ee 14 int deviceId;
s_ain 0:d0117f54a7ee 15 DeviceProperty property;
s_ain 0:d0117f54a7ee 16 } static const supportedDevices[] =
s_ain 0:d0117f54a7ee 17 {
s_ain 0:d0117f54a7ee 18 //SST25xF512A 512KBit (64KByte)
s_ain 0:d0117f54a7ee 19 { 0xbf, 0x48,
s_ain 0:d0117f54a7ee 20 {
s_ain 0:d0117f54a7ee 21 "SST25xF512A",
s_ain 0:d0117f54a7ee 22 512 * 1024 / 8,
s_ain 0:d0117f54a7ee 23 0xf3,
s_ain 0:d0117f54a7ee 24 1,
s_ain 0:d0117f54a7ee 25 &SST25DeviceImpl::writeAAI,
s_ain 0:d0117f54a7ee 26 33000000
s_ain 0:d0117f54a7ee 27 },
s_ain 0:d0117f54a7ee 28 },
s_ain 0:d0117f54a7ee 29 //SST25xF010A 1MBit (128KByte)
s_ain 0:d0117f54a7ee 30 { 0xbf, 0x49,
s_ain 0:d0117f54a7ee 31 {
s_ain 0:d0117f54a7ee 32 "SST25xF010A",
s_ain 0:d0117f54a7ee 33 1024 * 1024 / 8,
s_ain 0:d0117f54a7ee 34 0xf3,
s_ain 0:d0117f54a7ee 35 1,
s_ain 0:d0117f54a7ee 36 &SST25DeviceImpl::writeAAI,
s_ain 0:d0117f54a7ee 37 33000000
s_ain 0:d0117f54a7ee 38 },
s_ain 0:d0117f54a7ee 39 },
s_ain 0:d0117f54a7ee 40 //SST25xF020A 2MBit (256KByte)
s_ain 0:d0117f54a7ee 41 { 0xbf, 0x43,
s_ain 0:d0117f54a7ee 42 {
s_ain 0:d0117f54a7ee 43 "SST25xF020A",
s_ain 0:d0117f54a7ee 44 2048 * 1024 / 8,
s_ain 0:d0117f54a7ee 45 0xf3,
s_ain 0:d0117f54a7ee 46 1,
s_ain 0:d0117f54a7ee 47 &SST25DeviceImpl::writeAAI,
s_ain 0:d0117f54a7ee 48 33000000
s_ain 0:d0117f54a7ee 49 },
s_ain 0:d0117f54a7ee 50 },
s_ain 0:d0117f54a7ee 51 //SST25xF040B 4MBit (512KByte)
s_ain 0:d0117f54a7ee 52 { 0xbf, 0x8d,
s_ain 0:d0117f54a7ee 53 {
s_ain 0:d0117f54a7ee 54 "SST25xF040B",
s_ain 0:d0117f54a7ee 55 4096 * 1024 / 8,
s_ain 0:d0117f54a7ee 56 0xe3,
s_ain 0:d0117f54a7ee 57 1,
s_ain 0:d0117f54a7ee 58 &SST25DeviceImpl::writeAAIWord,
s_ain 0:d0117f54a7ee 59 46000000
s_ain 0:d0117f54a7ee 60 },
s_ain 0:d0117f54a7ee 61 },
s_ain 0:d0117f54a7ee 62 //SST25xF080B 8MBit (1MByte)
s_ain 0:d0117f54a7ee 63 { 0xbf, 0x8e,
s_ain 0:d0117f54a7ee 64 {
s_ain 0:d0117f54a7ee 65 "SST25xF080B",
s_ain 0:d0117f54a7ee 66 8192 * 1024 / 8,
s_ain 0:d0117f54a7ee 67 0xe3,
s_ain 0:d0117f54a7ee 68 1,
s_ain 0:d0117f54a7ee 69 &SST25DeviceImpl::writeAAIWord,
s_ain 0:d0117f54a7ee 70 46000000
s_ain 0:d0117f54a7ee 71 },
s_ain 0:d0117f54a7ee 72 },
s_ain 0:d0117f54a7ee 73 //SST25xF016B 16MBit (2MByte)
s_ain 0:d0117f54a7ee 74 { 0xbf, 0x41,
s_ain 0:d0117f54a7ee 75 {
s_ain 0:d0117f54a7ee 76 "SST25xF016B",
s_ain 0:d0117f54a7ee 77 16384 * 1024 / 8,
s_ain 0:d0117f54a7ee 78 0xe3,
s_ain 0:d0117f54a7ee 79 1,
s_ain 0:d0117f54a7ee 80 &SST25DeviceImpl::writeAAIWord,
s_ain 0:d0117f54a7ee 81 46000000
s_ain 0:d0117f54a7ee 82 },
s_ain 0:d0117f54a7ee 83 },
s_ain 0:d0117f54a7ee 84 //SST25xF032B 32MBit (4MByte)
s_ain 0:d0117f54a7ee 85 { 0xbf, 0x4a,
s_ain 0:d0117f54a7ee 86 {
s_ain 0:d0117f54a7ee 87 "SST25xF032B",
s_ain 0:d0117f54a7ee 88 32768 * 1024 / 8,
s_ain 0:d0117f54a7ee 89 0xc3,
s_ain 0:d0117f54a7ee 90 1,
s_ain 0:d0117f54a7ee 91 &SST25DeviceImpl::writeAAIWord,
s_ain 0:d0117f54a7ee 92 46000000
s_ain 0:d0117f54a7ee 93 },
s_ain 0:d0117f54a7ee 94 },
s_ain 0:d0117f54a7ee 95 //SST25xF064C 64MBit (8MByte)
s_ain 0:d0117f54a7ee 96 { 0xbf, 0x4b,
s_ain 0:d0117f54a7ee 97 {
s_ain 0:d0117f54a7ee 98 "SST25xF064C",
s_ain 0:d0117f54a7ee 99 65536 * 1024 / 8,
s_ain 0:d0117f54a7ee 100 0xc3,
s_ain 0:d0117f54a7ee 101 256,
s_ain 0:d0117f54a7ee 102 &SST25DeviceImpl::writePage,
s_ain 0:d0117f54a7ee 103 46000000
s_ain 0:d0117f54a7ee 104 },
s_ain 0:d0117f54a7ee 105 }
s_ain 0:d0117f54a7ee 106 };
s_ain 0:d0117f54a7ee 107 int count = sizeof(supportedDevices) / sizeof(supportedDevices[0]);
s_ain 0:d0117f54a7ee 108 for (int i = 0; i < count; ++i)
s_ain 0:d0117f54a7ee 109 {
s_ain 0:d0117f54a7ee 110 const SupportedDevice& device = supportedDevices[i];
s_ain 0:d0117f54a7ee 111 if (device.manufacturersId == manufacturersId && device.deviceId == deviceId)
s_ain 0:d0117f54a7ee 112 {
s_ain 0:d0117f54a7ee 113 return &device.property;
s_ain 0:d0117f54a7ee 114 }
s_ain 0:d0117f54a7ee 115 }
s_ain 0:d0117f54a7ee 116 return NULL;
s_ain 0:d0117f54a7ee 117 }
s_ain 0:d0117f54a7ee 118
s_ain 0:d0117f54a7ee 119 bool SST25DeviceImpl::IsSupported(ISPI* pSPI)
s_ain 0:d0117f54a7ee 120 {
s_ain 0:d0117f54a7ee 121 return findMatchDevice(pSPI) != NULL;
s_ain 0:d0117f54a7ee 122 }
s_ain 0:d0117f54a7ee 123
s_ain 0:d0117f54a7ee 124 SST25DeviceImpl* SST25DeviceImpl::Create(ISPI* pSPI)
s_ain 0:d0117f54a7ee 125 {
s_ain 0:d0117f54a7ee 126 const DeviceProperty* property = findMatchDevice(pSPI);
s_ain 0:d0117f54a7ee 127 if (property == NULL)
s_ain 0:d0117f54a7ee 128 {
s_ain 0:d0117f54a7ee 129 return NULL;
s_ain 0:d0117f54a7ee 130 }
s_ain 0:d0117f54a7ee 131 return new SST25DeviceImpl(pSPI, *property);
s_ain 0:d0117f54a7ee 132 }
s_ain 0:d0117f54a7ee 133
s_ain 0:d0117f54a7ee 134 SST25DeviceImpl::SST25DeviceImpl(ISPI* pSPI, const DeviceProperty& property)
s_ain 0:d0117f54a7ee 135 : _pSPI(pSPI)
s_ain 0:d0117f54a7ee 136 , _property(property)
s_ain 0:d0117f54a7ee 137 {
s_ain 0:d0117f54a7ee 138 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 139 _pSPI->SetFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 140 }
s_ain 0:d0117f54a7ee 141
s_ain 0:d0117f54a7ee 142 SST25DeviceImpl::~SST25DeviceImpl(void)
s_ain 0:d0117f54a7ee 143 {
s_ain 0:d0117f54a7ee 144
s_ain 0:d0117f54a7ee 145 }
s_ain 0:d0117f54a7ee 146
s_ain 0:d0117f54a7ee 147 void SST25DeviceImpl::readId(ISPI* pSPI, int& manufacturersId, int& deviceId)
s_ain 0:d0117f54a7ee 148 {
s_ain 0:d0117f54a7ee 149 const static int DefaultOperationFrequency = 20000000;
s_ain 0:d0117f54a7ee 150 pSPI->SetFrequency(DefaultOperationFrequency);
s_ain 0:d0117f54a7ee 151
s_ain 0:d0117f54a7ee 152 pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 153 pSPI->Write(0x90);
s_ain 0:d0117f54a7ee 154 pSPI->Write(0x00);
s_ain 0:d0117f54a7ee 155 pSPI->Write(0x00);
s_ain 0:d0117f54a7ee 156 pSPI->Write(0x00);
s_ain 0:d0117f54a7ee 157 manufacturersId = pSPI->Read();
s_ain 0:d0117f54a7ee 158 deviceId = pSPI->Read();
s_ain 0:d0117f54a7ee 159 pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 160 }
s_ain 0:d0117f54a7ee 161
s_ain 0:d0117f54a7ee 162 int SST25DeviceImpl::readStatusRegister(void)
s_ain 0:d0117f54a7ee 163 {
s_ain 0:d0117f54a7ee 164 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 165 _pSPI->Write(0x05);
s_ain 0:d0117f54a7ee 166 int result = _pSPI->Read();
s_ain 0:d0117f54a7ee 167 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 168 return result;
s_ain 0:d0117f54a7ee 169 }
s_ain 0:d0117f54a7ee 170
s_ain 0:d0117f54a7ee 171 void SST25DeviceImpl::writeStatusRegister(int value)
s_ain 0:d0117f54a7ee 172 {
s_ain 0:d0117f54a7ee 173 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 174 _pSPI->Write(0x50);
s_ain 0:d0117f54a7ee 175 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 176
s_ain 0:d0117f54a7ee 177 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 178 _pSPI->Write(0x01);
s_ain 0:d0117f54a7ee 179 _pSPI->Write(value);
s_ain 0:d0117f54a7ee 180 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 181 }
s_ain 0:d0117f54a7ee 182
s_ain 0:d0117f54a7ee 183 void SST25DeviceImpl::writeEnable()
s_ain 0:d0117f54a7ee 184 {
s_ain 0:d0117f54a7ee 185 int status = readStatusRegister();
s_ain 0:d0117f54a7ee 186 status &= _property.blockProtectionMask;
s_ain 0:d0117f54a7ee 187 writeStatusRegister(status);
s_ain 0:d0117f54a7ee 188
s_ain 0:d0117f54a7ee 189 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 190 _pSPI->Write(0x06);
s_ain 0:d0117f54a7ee 191 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 192 }
s_ain 0:d0117f54a7ee 193
s_ain 0:d0117f54a7ee 194 void SST25DeviceImpl::writeDisable()
s_ain 0:d0117f54a7ee 195 {
s_ain 0:d0117f54a7ee 196 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 197 _pSPI->Write(0x04);
s_ain 0:d0117f54a7ee 198 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 199 }
s_ain 0:d0117f54a7ee 200
s_ain 0:d0117f54a7ee 201 void SST25DeviceImpl::waitForReady()
s_ain 0:d0117f54a7ee 202 {
s_ain 0:d0117f54a7ee 203 while (readStatusRegister() & 0x01)
s_ain 0:d0117f54a7ee 204 ;
s_ain 0:d0117f54a7ee 205 }
s_ain 0:d0117f54a7ee 206
s_ain 0:d0117f54a7ee 207 std::string SST25DeviceImpl::GetDeviceName(void) const
s_ain 0:d0117f54a7ee 208 {
s_ain 0:d0117f54a7ee 209 return _property.deviceName;
s_ain 0:d0117f54a7ee 210 }
s_ain 0:d0117f54a7ee 211
s_ain 0:d0117f54a7ee 212 int SST25DeviceImpl::GetCapacity(void) const
s_ain 0:d0117f54a7ee 213 {
s_ain 0:d0117f54a7ee 214 return _property.capacity;
s_ain 0:d0117f54a7ee 215 }
s_ain 0:d0117f54a7ee 216
s_ain 0:d0117f54a7ee 217 int SST25DeviceImpl::Read(int address, void* buffer, int length)
s_ain 0:d0117f54a7ee 218 {
s_ain 0:d0117f54a7ee 219 if (address >= GetCapacity())
s_ain 0:d0117f54a7ee 220 {
s_ain 0:d0117f54a7ee 221 return 0;
s_ain 0:d0117f54a7ee 222 }
s_ain 0:d0117f54a7ee 223 if (address + length > GetCapacity())
s_ain 0:d0117f54a7ee 224 {
s_ain 0:d0117f54a7ee 225 length = GetCapacity() - address;
s_ain 0:d0117f54a7ee 226 }
s_ain 0:d0117f54a7ee 227 if (length == 0)
s_ain 0:d0117f54a7ee 228 {
s_ain 0:d0117f54a7ee 229 return 0;
s_ain 0:d0117f54a7ee 230 }
s_ain 0:d0117f54a7ee 231
s_ain 0:d0117f54a7ee 232 _pSPI->SetFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 233
s_ain 0:d0117f54a7ee 234 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 235 _pSPI->Write(0x0b);
s_ain 0:d0117f54a7ee 236 writeAddress(address);
s_ain 0:d0117f54a7ee 237 _pSPI->Write(0xff);
s_ain 0:d0117f54a7ee 238 _pSPI->Read(buffer, length);
s_ain 0:d0117f54a7ee 239 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 240 return length;
s_ain 0:d0117f54a7ee 241 }
s_ain 0:d0117f54a7ee 242
s_ain 0:d0117f54a7ee 243 int SST25DeviceImpl::Write(int address, const void* buffer, int length)
s_ain 0:d0117f54a7ee 244 {
s_ain 0:d0117f54a7ee 245 if (address >= GetCapacity())
s_ain 0:d0117f54a7ee 246 {
s_ain 0:d0117f54a7ee 247 return 0;
s_ain 0:d0117f54a7ee 248 }
s_ain 0:d0117f54a7ee 249 if (address + length > GetCapacity())
s_ain 0:d0117f54a7ee 250 {
s_ain 0:d0117f54a7ee 251 length = GetCapacity() - address;
s_ain 0:d0117f54a7ee 252 }
s_ain 0:d0117f54a7ee 253 if (length == 0)
s_ain 0:d0117f54a7ee 254 {
s_ain 0:d0117f54a7ee 255 return 0;
s_ain 0:d0117f54a7ee 256 }
s_ain 0:d0117f54a7ee 257 (this->*_property.pfnWriter)(address, buffer, length);
s_ain 0:d0117f54a7ee 258 return length;
s_ain 0:d0117f54a7ee 259 }
s_ain 0:d0117f54a7ee 260
s_ain 0:d0117f54a7ee 261 void SST25DeviceImpl::ChipErase()
s_ain 0:d0117f54a7ee 262 {
s_ain 0:d0117f54a7ee 263 _pSPI->SetFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 264
s_ain 0:d0117f54a7ee 265 writeEnable();
s_ain 0:d0117f54a7ee 266
s_ain 0:d0117f54a7ee 267 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 268 _pSPI->Write(0x60);
s_ain 0:d0117f54a7ee 269 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 270 waitForReady();
s_ain 0:d0117f54a7ee 271 }
s_ain 0:d0117f54a7ee 272
s_ain 0:d0117f54a7ee 273 void SST25DeviceImpl::byteProgram(int address, int value)
s_ain 0:d0117f54a7ee 274 {
s_ain 0:d0117f54a7ee 275 _pSPI->SetFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 276
s_ain 0:d0117f54a7ee 277 writeEnable();
s_ain 0:d0117f54a7ee 278
s_ain 0:d0117f54a7ee 279 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 280 _pSPI->Write(0x02);
s_ain 0:d0117f54a7ee 281 writeAddress(address);
s_ain 0:d0117f54a7ee 282 _pSPI->Write(value);
s_ain 0:d0117f54a7ee 283 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 284 waitForReady();
s_ain 0:d0117f54a7ee 285 }
s_ain 0:d0117f54a7ee 286
s_ain 0:d0117f54a7ee 287 void SST25DeviceImpl::beginAAIProgram(int address, int data)
s_ain 0:d0117f54a7ee 288 {
s_ain 0:d0117f54a7ee 289 _pSPI->SetFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 290
s_ain 0:d0117f54a7ee 291 writeEnable();
s_ain 0:d0117f54a7ee 292
s_ain 0:d0117f54a7ee 293 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 294 _pSPI->Write(0xaf);
s_ain 0:d0117f54a7ee 295 writeAddress(address);
s_ain 0:d0117f54a7ee 296 _pSPI->Write(data);
s_ain 0:d0117f54a7ee 297 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 298 waitForReady();
s_ain 0:d0117f54a7ee 299 }
s_ain 0:d0117f54a7ee 300
s_ain 0:d0117f54a7ee 301 void SST25DeviceImpl::nextAAIProgram(int data)
s_ain 0:d0117f54a7ee 302 {
s_ain 0:d0117f54a7ee 303 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 304 _pSPI->Write(0xaf);
s_ain 0:d0117f54a7ee 305 _pSPI->Write(data);
s_ain 0:d0117f54a7ee 306 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 307 waitForReady();
s_ain 0:d0117f54a7ee 308 }
s_ain 0:d0117f54a7ee 309
s_ain 0:d0117f54a7ee 310 void SST25DeviceImpl::endAAIProgram(void)
s_ain 0:d0117f54a7ee 311 {
s_ain 0:d0117f54a7ee 312 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 313 _pSPI->Write(0x04);
s_ain 0:d0117f54a7ee 314 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 315 waitForReady();
s_ain 0:d0117f54a7ee 316 }
s_ain 0:d0117f54a7ee 317
s_ain 0:d0117f54a7ee 318 void SST25DeviceImpl::beginAAIWordProgram(int address, int data)
s_ain 0:d0117f54a7ee 319 {
s_ain 0:d0117f54a7ee 320 _pSPI->SetFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 321
s_ain 0:d0117f54a7ee 322 writeEnable();
s_ain 0:d0117f54a7ee 323
s_ain 0:d0117f54a7ee 324 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 325 _pSPI->Write(0xad);
s_ain 0:d0117f54a7ee 326 writeAddress(address);
s_ain 0:d0117f54a7ee 327 _pSPI->Write((data & 0xff00) >> 8);
s_ain 0:d0117f54a7ee 328 _pSPI->Write(data & 0xff);
s_ain 0:d0117f54a7ee 329 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 330 waitForReady();
s_ain 0:d0117f54a7ee 331 }
s_ain 0:d0117f54a7ee 332
s_ain 0:d0117f54a7ee 333 void SST25DeviceImpl::nextAAIWordProgram(int data)
s_ain 0:d0117f54a7ee 334 {
s_ain 0:d0117f54a7ee 335 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 336 _pSPI->Write(0xad);
s_ain 0:d0117f54a7ee 337 _pSPI->Write((data & 0xff00) >> 8);
s_ain 0:d0117f54a7ee 338 _pSPI->Write(data & 0xff);
s_ain 0:d0117f54a7ee 339 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 340 waitForReady();
s_ain 0:d0117f54a7ee 341 }
s_ain 0:d0117f54a7ee 342
s_ain 0:d0117f54a7ee 343 void SST25DeviceImpl::writeAddress(int address)
s_ain 0:d0117f54a7ee 344 {
s_ain 0:d0117f54a7ee 345 _pSPI->Write((address & 0xff0000) >> 16);
s_ain 0:d0117f54a7ee 346 _pSPI->Write((address & 0xff00) >> 8);
s_ain 0:d0117f54a7ee 347 _pSPI->Write(address & 0xff);
s_ain 0:d0117f54a7ee 348 }
s_ain 0:d0117f54a7ee 349
s_ain 0:d0117f54a7ee 350 void SST25DeviceImpl::pageProgram(int address, const void* buffer)
s_ain 0:d0117f54a7ee 351 {
s_ain 0:d0117f54a7ee 352 _pSPI->SetFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 353
s_ain 0:d0117f54a7ee 354 writeEnable();
s_ain 0:d0117f54a7ee 355
s_ain 0:d0117f54a7ee 356 _pSPI->ChangeCS(ISPI::Low);
s_ain 0:d0117f54a7ee 357 _pSPI->Write(0x02);
s_ain 0:d0117f54a7ee 358 writeAddress(address);
s_ain 1:385965a14c7c 359 _pSPI->Write(buffer, 256);
s_ain 0:d0117f54a7ee 360 _pSPI->ChangeCS(ISPI::High);
s_ain 0:d0117f54a7ee 361 waitForReady();
s_ain 0:d0117f54a7ee 362 }
s_ain 0:d0117f54a7ee 363
s_ain 0:d0117f54a7ee 364 void SST25DeviceImpl::writePage(int address, const void* buffer, int length)
s_ain 0:d0117f54a7ee 365 {
s_ain 0:d0117f54a7ee 366 int pageSize = _property.pageSize;
s_ain 0:d0117f54a7ee 367 int pageSizeMask = pageSize - 1;
s_ain 0:d0117f54a7ee 368 int pageAddressMask = ~pageSizeMask;
s_ain 0:d0117f54a7ee 369
s_ain 0:d0117f54a7ee 370 if (length <= 0)
s_ain 0:d0117f54a7ee 371 {
s_ain 0:d0117f54a7ee 372 return;
s_ain 0:d0117f54a7ee 373 }
s_ain 0:d0117f54a7ee 374 const unsigned char* p = static_cast<const unsigned char*>(buffer);
s_ain 0:d0117f54a7ee 375 if ((address & pageSizeMask) != 0)
s_ain 0:d0117f54a7ee 376 {
s_ain 0:d0117f54a7ee 377 int readLen = address & pageSizeMask;
s_ain 0:d0117f54a7ee 378 int copyLen = pageSize - readLen;
s_ain 0:d0117f54a7ee 379 if (copyLen > length)
s_ain 0:d0117f54a7ee 380 {
s_ain 0:d0117f54a7ee 381 copyLen = length;
s_ain 0:d0117f54a7ee 382 }
s_ain 0:d0117f54a7ee 383 char buf[pageSize];
s_ain 0:d0117f54a7ee 384 int writeAddress = address & pageAddressMask;
s_ain 0:d0117f54a7ee 385 Read(writeAddress, buf, readLen);
s_ain 0:d0117f54a7ee 386 memcpy(&buf[address & pageSizeMask], buffer, copyLen);
s_ain 0:d0117f54a7ee 387 pageProgram(writeAddress, buf);
s_ain 0:d0117f54a7ee 388 p += readLen;
s_ain 0:d0117f54a7ee 389 address += pageSize - readLen;
s_ain 0:d0117f54a7ee 390 length -= copyLen;
s_ain 0:d0117f54a7ee 391 }
s_ain 0:d0117f54a7ee 392 while (length >= pageSize)
s_ain 0:d0117f54a7ee 393 {
s_ain 0:d0117f54a7ee 394 pageProgram(address, p);
s_ain 0:d0117f54a7ee 395 address += pageSize;
s_ain 0:d0117f54a7ee 396 p += pageSize;
s_ain 0:d0117f54a7ee 397 length -= pageSize;
s_ain 0:d0117f54a7ee 398 }
s_ain 0:d0117f54a7ee 399 if (length != 0)
s_ain 0:d0117f54a7ee 400 {
s_ain 0:d0117f54a7ee 401 char buf[pageSize];
s_ain 0:d0117f54a7ee 402 memcpy(buf, p, length);
s_ain 0:d0117f54a7ee 403 memset(&buf[length], 0xff, pageSize - length);
s_ain 0:d0117f54a7ee 404 pageProgram(address, buf);
s_ain 0:d0117f54a7ee 405 }
s_ain 0:d0117f54a7ee 406 }
s_ain 0:d0117f54a7ee 407
s_ain 0:d0117f54a7ee 408 void SST25DeviceImpl::writeBytes(int address, const void* buffer, int length)
s_ain 0:d0117f54a7ee 409 {
s_ain 0:d0117f54a7ee 410 const unsigned char* p = static_cast<const unsigned char*>(buffer);
s_ain 0:d0117f54a7ee 411 while (length-- >= 0)
s_ain 0:d0117f54a7ee 412 {
s_ain 0:d0117f54a7ee 413 byteProgram(address++, *p++);
s_ain 0:d0117f54a7ee 414 }
s_ain 0:d0117f54a7ee 415 }
s_ain 0:d0117f54a7ee 416
s_ain 0:d0117f54a7ee 417 void SST25DeviceImpl::writeAAI(int address, const void* buffer, int length)
s_ain 0:d0117f54a7ee 418 {
s_ain 0:d0117f54a7ee 419 if (length <= 0)
s_ain 0:d0117f54a7ee 420 {
s_ain 0:d0117f54a7ee 421 return;
s_ain 0:d0117f54a7ee 422 }
s_ain 0:d0117f54a7ee 423
s_ain 0:d0117f54a7ee 424 const unsigned char* p = static_cast<const unsigned char*>(buffer);
s_ain 0:d0117f54a7ee 425 if (length < 2)
s_ain 0:d0117f54a7ee 426 {
s_ain 0:d0117f54a7ee 427 byteProgram(address, *p);
s_ain 0:d0117f54a7ee 428 return;
s_ain 0:d0117f54a7ee 429 }
s_ain 0:d0117f54a7ee 430
s_ain 0:d0117f54a7ee 431 beginAAIProgram(address, *p++);
s_ain 0:d0117f54a7ee 432 while (--length != 0)
s_ain 0:d0117f54a7ee 433 {
s_ain 0:d0117f54a7ee 434 nextAAIProgram(*p++);
s_ain 0:d0117f54a7ee 435 }
s_ain 0:d0117f54a7ee 436 endAAIProgram();
s_ain 0:d0117f54a7ee 437 }
s_ain 0:d0117f54a7ee 438
s_ain 0:d0117f54a7ee 439 void SST25DeviceImpl::writeAAIWord(int address, const void* buffer, int length)
s_ain 0:d0117f54a7ee 440 {
s_ain 0:d0117f54a7ee 441 if (length <= 0)
s_ain 0:d0117f54a7ee 442 {
s_ain 0:d0117f54a7ee 443 return;
s_ain 0:d0117f54a7ee 444 }
s_ain 0:d0117f54a7ee 445
s_ain 0:d0117f54a7ee 446 const unsigned char* p = static_cast<const unsigned char*>(buffer);
s_ain 0:d0117f54a7ee 447 if ((address & 0x1) != 0)
s_ain 0:d0117f54a7ee 448 {
s_ain 0:d0117f54a7ee 449 byteProgram(address++, *p++);
s_ain 0:d0117f54a7ee 450 length--;
s_ain 0:d0117f54a7ee 451 }
s_ain 0:d0117f54a7ee 452
s_ain 0:d0117f54a7ee 453 if (length < 4)
s_ain 0:d0117f54a7ee 454 {
s_ain 0:d0117f54a7ee 455 writeBytes(address, p, length);
s_ain 0:d0117f54a7ee 456 return;
s_ain 0:d0117f54a7ee 457 }
s_ain 0:d0117f54a7ee 458
s_ain 0:d0117f54a7ee 459 beginAAIWordProgram(address, (*p << 8) | *(p + 1));
s_ain 0:d0117f54a7ee 460 address += length & ~0x1;
s_ain 0:d0117f54a7ee 461 p += 2;
s_ain 0:d0117f54a7ee 462 length -= 2;
s_ain 0:d0117f54a7ee 463
s_ain 0:d0117f54a7ee 464 do
s_ain 0:d0117f54a7ee 465 {
s_ain 0:d0117f54a7ee 466 nextAAIWordProgram((*p << 8) | *(p + 1));
s_ain 0:d0117f54a7ee 467 p += 2;
s_ain 0:d0117f54a7ee 468 length -= 2;
s_ain 0:d0117f54a7ee 469 } while (length >= 2);
s_ain 0:d0117f54a7ee 470 endAAIProgram();
s_ain 0:d0117f54a7ee 471
s_ain 0:d0117f54a7ee 472 if (length != 0)
s_ain 0:d0117f54a7ee 473 {
s_ain 0:d0117f54a7ee 474 byteProgram(address, *p);
s_ain 0:d0117f54a7ee 475 }
s_ain 0:d0117f54a7ee 476 }