Seiji Ainoguchi / SerialFlash

Dependents:   SerialFlashTest

Fork of SerialFlash by Seiji Ainoguchi

Committer:
s_ain
Date:
Wed Mar 02 16:09:09 2011 +0000
Revision:
2:6f8ab876b516
Parent:
1:385965a14c7c
change SPI interface

Who changed what in which revision?

UserRevisionLine numberNew contents of line
s_ain 2:6f8ab876b516 1 #include "ISPICommand.h"
s_ain 0:d0117f54a7ee 2 #include <string.h>
s_ain 0:d0117f54a7ee 3 #include "SST25DeviceImpl.h"
s_ain 0:d0117f54a7ee 4
s_ain 2:6f8ab876b516 5 const SST25DeviceImpl::DeviceProperty* SST25DeviceImpl::findMatchDevice(ISPICommand* pSPICommand)
s_ain 0:d0117f54a7ee 6 {
s_ain 0:d0117f54a7ee 7 int manufacturersId;
s_ain 0:d0117f54a7ee 8 int deviceId;
s_ain 2:6f8ab876b516 9 readId(pSPICommand, 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 2:6f8ab876b516 59 50000000
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 2:6f8ab876b516 70 50000000
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 2:6f8ab876b516 81 50000000
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 2:6f8ab876b516 92 50000000
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 2:6f8ab876b516 103 50000000
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 2:6f8ab876b516 119 bool SST25DeviceImpl::IsSupported(ISPICommand* pSPICommand)
s_ain 0:d0117f54a7ee 120 {
s_ain 2:6f8ab876b516 121 return findMatchDevice(pSPICommand) != NULL;
s_ain 0:d0117f54a7ee 122 }
s_ain 0:d0117f54a7ee 123
s_ain 2:6f8ab876b516 124 SST25DeviceImpl* SST25DeviceImpl::Create(ISPICommand* pSPICommand)
s_ain 0:d0117f54a7ee 125 {
s_ain 2:6f8ab876b516 126 const DeviceProperty* property = findMatchDevice(pSPICommand);
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 2:6f8ab876b516 131 return new SST25DeviceImpl(pSPICommand, *property);
s_ain 0:d0117f54a7ee 132 }
s_ain 0:d0117f54a7ee 133
s_ain 2:6f8ab876b516 134 SST25DeviceImpl::SST25DeviceImpl(ISPICommand* pSPICommand, const DeviceProperty& property)
s_ain 2:6f8ab876b516 135 : _pSPICommand(pSPICommand)
s_ain 0:d0117f54a7ee 136 , _property(property)
s_ain 0:d0117f54a7ee 137 {
s_ain 2:6f8ab876b516 138 _pSPICommand->SetMaxFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 139 }
s_ain 0:d0117f54a7ee 140
s_ain 0:d0117f54a7ee 141 SST25DeviceImpl::~SST25DeviceImpl(void)
s_ain 0:d0117f54a7ee 142 {
s_ain 0:d0117f54a7ee 143
s_ain 0:d0117f54a7ee 144 }
s_ain 0:d0117f54a7ee 145
s_ain 2:6f8ab876b516 146 void SST25DeviceImpl::readId(ISPICommand* pSPICommand, int& manufacturersId, int& deviceId)
s_ain 0:d0117f54a7ee 147 {
s_ain 0:d0117f54a7ee 148 const static int DefaultOperationFrequency = 20000000;
s_ain 2:6f8ab876b516 149 pSPICommand->SetMaxFrequency(DefaultOperationFrequency);
s_ain 0:d0117f54a7ee 150
s_ain 2:6f8ab876b516 151 unsigned char read[2];
s_ain 2:6f8ab876b516 152 char param[3];
s_ain 2:6f8ab876b516 153 fillAddress(param, 0x000000);
s_ain 2:6f8ab876b516 154 pSPICommand->Read(0x90, param, sizeof(param), read, sizeof(read));
s_ain 2:6f8ab876b516 155 manufacturersId = read[0];
s_ain 2:6f8ab876b516 156 deviceId = read[1];
s_ain 0:d0117f54a7ee 157 }
s_ain 0:d0117f54a7ee 158
s_ain 0:d0117f54a7ee 159 int SST25DeviceImpl::readStatusRegister(void)
s_ain 0:d0117f54a7ee 160 {
s_ain 2:6f8ab876b516 161 unsigned char read;
s_ain 2:6f8ab876b516 162 _pSPICommand->Read(0x05, &read, 1);
s_ain 2:6f8ab876b516 163 return read;
s_ain 0:d0117f54a7ee 164 }
s_ain 0:d0117f54a7ee 165
s_ain 0:d0117f54a7ee 166 void SST25DeviceImpl::writeStatusRegister(int value)
s_ain 0:d0117f54a7ee 167 {
s_ain 2:6f8ab876b516 168 _pSPICommand->Write(0x50);
s_ain 0:d0117f54a7ee 169
s_ain 2:6f8ab876b516 170 char vb = static_cast<char>(value);
s_ain 2:6f8ab876b516 171 _pSPICommand->Write(0x01, &vb, sizeof(vb));
s_ain 0:d0117f54a7ee 172 }
s_ain 0:d0117f54a7ee 173
s_ain 0:d0117f54a7ee 174 void SST25DeviceImpl::writeEnable()
s_ain 0:d0117f54a7ee 175 {
s_ain 0:d0117f54a7ee 176 int status = readStatusRegister();
s_ain 0:d0117f54a7ee 177 status &= _property.blockProtectionMask;
s_ain 0:d0117f54a7ee 178 writeStatusRegister(status);
s_ain 2:6f8ab876b516 179 _pSPICommand->Write(0x06);
s_ain 0:d0117f54a7ee 180 }
s_ain 0:d0117f54a7ee 181
s_ain 0:d0117f54a7ee 182 void SST25DeviceImpl::writeDisable()
s_ain 0:d0117f54a7ee 183 {
s_ain 2:6f8ab876b516 184 _pSPICommand->Write(0x04);
s_ain 0:d0117f54a7ee 185 }
s_ain 0:d0117f54a7ee 186
s_ain 0:d0117f54a7ee 187 void SST25DeviceImpl::waitForReady()
s_ain 0:d0117f54a7ee 188 {
s_ain 0:d0117f54a7ee 189 while (readStatusRegister() & 0x01)
s_ain 0:d0117f54a7ee 190 ;
s_ain 0:d0117f54a7ee 191 }
s_ain 0:d0117f54a7ee 192
s_ain 0:d0117f54a7ee 193 std::string SST25DeviceImpl::GetDeviceName(void) const
s_ain 0:d0117f54a7ee 194 {
s_ain 0:d0117f54a7ee 195 return _property.deviceName;
s_ain 0:d0117f54a7ee 196 }
s_ain 0:d0117f54a7ee 197
s_ain 0:d0117f54a7ee 198 int SST25DeviceImpl::GetCapacity(void) const
s_ain 0:d0117f54a7ee 199 {
s_ain 0:d0117f54a7ee 200 return _property.capacity;
s_ain 0:d0117f54a7ee 201 }
s_ain 0:d0117f54a7ee 202
s_ain 0:d0117f54a7ee 203 int SST25DeviceImpl::Read(int address, void* buffer, int length)
s_ain 0:d0117f54a7ee 204 {
s_ain 0:d0117f54a7ee 205 if (address >= GetCapacity())
s_ain 0:d0117f54a7ee 206 {
s_ain 0:d0117f54a7ee 207 return 0;
s_ain 0:d0117f54a7ee 208 }
s_ain 0:d0117f54a7ee 209 if (address + length > GetCapacity())
s_ain 0:d0117f54a7ee 210 {
s_ain 0:d0117f54a7ee 211 length = GetCapacity() - address;
s_ain 0:d0117f54a7ee 212 }
s_ain 0:d0117f54a7ee 213 if (length == 0)
s_ain 0:d0117f54a7ee 214 {
s_ain 0:d0117f54a7ee 215 return 0;
s_ain 0:d0117f54a7ee 216 }
s_ain 0:d0117f54a7ee 217
s_ain 2:6f8ab876b516 218 _pSPICommand->SetMaxFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 219
s_ain 2:6f8ab876b516 220 char param[] = { 0, 0, 0, 0xff };
s_ain 2:6f8ab876b516 221 fillAddress(param, address);
s_ain 2:6f8ab876b516 222 _pSPICommand->Read(0x0b, param, sizeof(param), buffer, length);
s_ain 0:d0117f54a7ee 223 return length;
s_ain 0:d0117f54a7ee 224 }
s_ain 0:d0117f54a7ee 225
s_ain 0:d0117f54a7ee 226 int SST25DeviceImpl::Write(int address, const void* buffer, int length)
s_ain 0:d0117f54a7ee 227 {
s_ain 0:d0117f54a7ee 228 if (address >= GetCapacity())
s_ain 0:d0117f54a7ee 229 {
s_ain 0:d0117f54a7ee 230 return 0;
s_ain 0:d0117f54a7ee 231 }
s_ain 0:d0117f54a7ee 232 if (address + length > GetCapacity())
s_ain 0:d0117f54a7ee 233 {
s_ain 0:d0117f54a7ee 234 length = GetCapacity() - address;
s_ain 0:d0117f54a7ee 235 }
s_ain 0:d0117f54a7ee 236 if (length == 0)
s_ain 0:d0117f54a7ee 237 {
s_ain 0:d0117f54a7ee 238 return 0;
s_ain 0:d0117f54a7ee 239 }
s_ain 0:d0117f54a7ee 240 (this->*_property.pfnWriter)(address, buffer, length);
s_ain 0:d0117f54a7ee 241 return length;
s_ain 0:d0117f54a7ee 242 }
s_ain 0:d0117f54a7ee 243
s_ain 0:d0117f54a7ee 244 void SST25DeviceImpl::ChipErase()
s_ain 0:d0117f54a7ee 245 {
s_ain 2:6f8ab876b516 246 _pSPICommand->SetMaxFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 247
s_ain 0:d0117f54a7ee 248 writeEnable();
s_ain 2:6f8ab876b516 249 _pSPICommand->Write(0x60);
s_ain 0:d0117f54a7ee 250 waitForReady();
s_ain 0:d0117f54a7ee 251 }
s_ain 0:d0117f54a7ee 252
s_ain 0:d0117f54a7ee 253 void SST25DeviceImpl::byteProgram(int address, int value)
s_ain 0:d0117f54a7ee 254 {
s_ain 2:6f8ab876b516 255 _pSPICommand->SetMaxFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 256
s_ain 0:d0117f54a7ee 257 writeEnable();
s_ain 0:d0117f54a7ee 258
s_ain 2:6f8ab876b516 259 char param[] = { 0, 0, 0, value };
s_ain 2:6f8ab876b516 260 fillAddress(param, address);
s_ain 2:6f8ab876b516 261 _pSPICommand->Write(0x02, param, sizeof(param));
s_ain 2:6f8ab876b516 262
s_ain 0:d0117f54a7ee 263 waitForReady();
s_ain 0:d0117f54a7ee 264 }
s_ain 0:d0117f54a7ee 265
s_ain 0:d0117f54a7ee 266 void SST25DeviceImpl::beginAAIProgram(int address, int data)
s_ain 0:d0117f54a7ee 267 {
s_ain 2:6f8ab876b516 268 _pSPICommand->SetMaxFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 269
s_ain 0:d0117f54a7ee 270 writeEnable();
s_ain 2:6f8ab876b516 271
s_ain 2:6f8ab876b516 272 char param[] = { 0, 0, 0, data };
s_ain 2:6f8ab876b516 273 fillAddress(param, address);
s_ain 2:6f8ab876b516 274 _pSPICommand->Write(0xaf, param, sizeof(param));
s_ain 0:d0117f54a7ee 275
s_ain 0:d0117f54a7ee 276 waitForReady();
s_ain 0:d0117f54a7ee 277 }
s_ain 0:d0117f54a7ee 278
s_ain 0:d0117f54a7ee 279 void SST25DeviceImpl::nextAAIProgram(int data)
s_ain 0:d0117f54a7ee 280 {
s_ain 2:6f8ab876b516 281 char param = static_cast<char>(data);
s_ain 2:6f8ab876b516 282 _pSPICommand->Write(0xaf, &param, 1);
s_ain 2:6f8ab876b516 283
s_ain 0:d0117f54a7ee 284 waitForReady();
s_ain 0:d0117f54a7ee 285 }
s_ain 0:d0117f54a7ee 286
s_ain 0:d0117f54a7ee 287 void SST25DeviceImpl::endAAIProgram(void)
s_ain 0:d0117f54a7ee 288 {
s_ain 2:6f8ab876b516 289 _pSPICommand->Write(0x04);
s_ain 0:d0117f54a7ee 290 waitForReady();
s_ain 0:d0117f54a7ee 291 }
s_ain 0:d0117f54a7ee 292
s_ain 0:d0117f54a7ee 293 void SST25DeviceImpl::beginAAIWordProgram(int address, int data)
s_ain 0:d0117f54a7ee 294 {
s_ain 2:6f8ab876b516 295 _pSPICommand->SetMaxFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 296
s_ain 0:d0117f54a7ee 297 writeEnable();
s_ain 2:6f8ab876b516 298 char param[] = { 0, 0, 0, (data & 0xff00) >> 8, data & 0xff };
s_ain 2:6f8ab876b516 299 fillAddress(param, address);
s_ain 2:6f8ab876b516 300 _pSPICommand->Write(0xad, param, sizeof(param));
s_ain 0:d0117f54a7ee 301 waitForReady();
s_ain 0:d0117f54a7ee 302 }
s_ain 0:d0117f54a7ee 303
s_ain 0:d0117f54a7ee 304 void SST25DeviceImpl::nextAAIWordProgram(int data)
s_ain 0:d0117f54a7ee 305 {
s_ain 2:6f8ab876b516 306 char param[] = { (data & 0xff00) >> 8, data & 0xff };
s_ain 2:6f8ab876b516 307 _pSPICommand->Write(0xad, param, sizeof(param));
s_ain 0:d0117f54a7ee 308 waitForReady();
s_ain 0:d0117f54a7ee 309 }
s_ain 0:d0117f54a7ee 310
s_ain 2:6f8ab876b516 311 void SST25DeviceImpl::fillAddress(char* pBuffer, int address)
s_ain 0:d0117f54a7ee 312 {
s_ain 2:6f8ab876b516 313 *(pBuffer + 0) = (address & 0xff0000) >> 16;
s_ain 2:6f8ab876b516 314 *(pBuffer + 1) = (address & 0x00ff00) >> 8;
s_ain 2:6f8ab876b516 315 *(pBuffer + 2) = (address & 0x0000ff);
s_ain 0:d0117f54a7ee 316 }
s_ain 0:d0117f54a7ee 317
s_ain 0:d0117f54a7ee 318 void SST25DeviceImpl::pageProgram(int address, const void* buffer)
s_ain 0:d0117f54a7ee 319 {
s_ain 2:6f8ab876b516 320 _pSPICommand->SetMaxFrequency(_property.operationClkHz);
s_ain 0:d0117f54a7ee 321
s_ain 0:d0117f54a7ee 322 writeEnable();
s_ain 0:d0117f54a7ee 323
s_ain 2:6f8ab876b516 324 char param[256 + 3];
s_ain 2:6f8ab876b516 325 fillAddress(param, address);
s_ain 2:6f8ab876b516 326 memcpy(param + 3, buffer, 256);
s_ain 2:6f8ab876b516 327 _pSPICommand->Write(0x02, param, sizeof(param));
s_ain 2:6f8ab876b516 328
s_ain 0:d0117f54a7ee 329 waitForReady();
s_ain 0:d0117f54a7ee 330 }
s_ain 0:d0117f54a7ee 331
s_ain 0:d0117f54a7ee 332 void SST25DeviceImpl::writePage(int address, const void* buffer, int length)
s_ain 0:d0117f54a7ee 333 {
s_ain 0:d0117f54a7ee 334 int pageSize = _property.pageSize;
s_ain 0:d0117f54a7ee 335 int pageSizeMask = pageSize - 1;
s_ain 0:d0117f54a7ee 336 int pageAddressMask = ~pageSizeMask;
s_ain 0:d0117f54a7ee 337
s_ain 0:d0117f54a7ee 338 if (length <= 0)
s_ain 0:d0117f54a7ee 339 {
s_ain 0:d0117f54a7ee 340 return;
s_ain 0:d0117f54a7ee 341 }
s_ain 0:d0117f54a7ee 342 const unsigned char* p = static_cast<const unsigned char*>(buffer);
s_ain 0:d0117f54a7ee 343 if ((address & pageSizeMask) != 0)
s_ain 0:d0117f54a7ee 344 {
s_ain 0:d0117f54a7ee 345 int readLen = address & pageSizeMask;
s_ain 0:d0117f54a7ee 346 int copyLen = pageSize - readLen;
s_ain 0:d0117f54a7ee 347 if (copyLen > length)
s_ain 0:d0117f54a7ee 348 {
s_ain 0:d0117f54a7ee 349 copyLen = length;
s_ain 0:d0117f54a7ee 350 }
s_ain 0:d0117f54a7ee 351 char buf[pageSize];
s_ain 0:d0117f54a7ee 352 int writeAddress = address & pageAddressMask;
s_ain 0:d0117f54a7ee 353 Read(writeAddress, buf, readLen);
s_ain 0:d0117f54a7ee 354 memcpy(&buf[address & pageSizeMask], buffer, copyLen);
s_ain 0:d0117f54a7ee 355 pageProgram(writeAddress, buf);
s_ain 0:d0117f54a7ee 356 p += readLen;
s_ain 0:d0117f54a7ee 357 address += pageSize - readLen;
s_ain 0:d0117f54a7ee 358 length -= copyLen;
s_ain 0:d0117f54a7ee 359 }
s_ain 0:d0117f54a7ee 360 while (length >= pageSize)
s_ain 0:d0117f54a7ee 361 {
s_ain 0:d0117f54a7ee 362 pageProgram(address, p);
s_ain 0:d0117f54a7ee 363 address += pageSize;
s_ain 0:d0117f54a7ee 364 p += pageSize;
s_ain 0:d0117f54a7ee 365 length -= pageSize;
s_ain 0:d0117f54a7ee 366 }
s_ain 0:d0117f54a7ee 367 if (length != 0)
s_ain 0:d0117f54a7ee 368 {
s_ain 0:d0117f54a7ee 369 char buf[pageSize];
s_ain 0:d0117f54a7ee 370 memcpy(buf, p, length);
s_ain 0:d0117f54a7ee 371 memset(&buf[length], 0xff, pageSize - length);
s_ain 0:d0117f54a7ee 372 pageProgram(address, buf);
s_ain 0:d0117f54a7ee 373 }
s_ain 0:d0117f54a7ee 374 }
s_ain 0:d0117f54a7ee 375
s_ain 0:d0117f54a7ee 376 void SST25DeviceImpl::writeBytes(int address, const void* buffer, int length)
s_ain 0:d0117f54a7ee 377 {
s_ain 0:d0117f54a7ee 378 const unsigned char* p = static_cast<const unsigned char*>(buffer);
s_ain 0:d0117f54a7ee 379 while (length-- >= 0)
s_ain 0:d0117f54a7ee 380 {
s_ain 0:d0117f54a7ee 381 byteProgram(address++, *p++);
s_ain 0:d0117f54a7ee 382 }
s_ain 0:d0117f54a7ee 383 }
s_ain 0:d0117f54a7ee 384
s_ain 0:d0117f54a7ee 385 void SST25DeviceImpl::writeAAI(int address, const void* buffer, int length)
s_ain 0:d0117f54a7ee 386 {
s_ain 0:d0117f54a7ee 387 if (length <= 0)
s_ain 0:d0117f54a7ee 388 {
s_ain 0:d0117f54a7ee 389 return;
s_ain 0:d0117f54a7ee 390 }
s_ain 0:d0117f54a7ee 391
s_ain 0:d0117f54a7ee 392 const unsigned char* p = static_cast<const unsigned char*>(buffer);
s_ain 0:d0117f54a7ee 393 if (length < 2)
s_ain 0:d0117f54a7ee 394 {
s_ain 0:d0117f54a7ee 395 byteProgram(address, *p);
s_ain 0:d0117f54a7ee 396 return;
s_ain 0:d0117f54a7ee 397 }
s_ain 0:d0117f54a7ee 398
s_ain 0:d0117f54a7ee 399 beginAAIProgram(address, *p++);
s_ain 0:d0117f54a7ee 400 while (--length != 0)
s_ain 0:d0117f54a7ee 401 {
s_ain 0:d0117f54a7ee 402 nextAAIProgram(*p++);
s_ain 0:d0117f54a7ee 403 }
s_ain 0:d0117f54a7ee 404 endAAIProgram();
s_ain 0:d0117f54a7ee 405 }
s_ain 0:d0117f54a7ee 406
s_ain 0:d0117f54a7ee 407 void SST25DeviceImpl::writeAAIWord(int address, const void* buffer, int length)
s_ain 0:d0117f54a7ee 408 {
s_ain 0:d0117f54a7ee 409 if (length <= 0)
s_ain 0:d0117f54a7ee 410 {
s_ain 0:d0117f54a7ee 411 return;
s_ain 0:d0117f54a7ee 412 }
s_ain 0:d0117f54a7ee 413
s_ain 0:d0117f54a7ee 414 const unsigned char* p = static_cast<const unsigned char*>(buffer);
s_ain 0:d0117f54a7ee 415 if ((address & 0x1) != 0)
s_ain 0:d0117f54a7ee 416 {
s_ain 0:d0117f54a7ee 417 byteProgram(address++, *p++);
s_ain 0:d0117f54a7ee 418 length--;
s_ain 0:d0117f54a7ee 419 }
s_ain 0:d0117f54a7ee 420
s_ain 0:d0117f54a7ee 421 if (length < 4)
s_ain 0:d0117f54a7ee 422 {
s_ain 0:d0117f54a7ee 423 writeBytes(address, p, length);
s_ain 0:d0117f54a7ee 424 return;
s_ain 0:d0117f54a7ee 425 }
s_ain 0:d0117f54a7ee 426
s_ain 0:d0117f54a7ee 427 beginAAIWordProgram(address, (*p << 8) | *(p + 1));
s_ain 0:d0117f54a7ee 428 address += length & ~0x1;
s_ain 0:d0117f54a7ee 429 p += 2;
s_ain 0:d0117f54a7ee 430 length -= 2;
s_ain 0:d0117f54a7ee 431
s_ain 0:d0117f54a7ee 432 do
s_ain 0:d0117f54a7ee 433 {
s_ain 0:d0117f54a7ee 434 nextAAIWordProgram((*p << 8) | *(p + 1));
s_ain 0:d0117f54a7ee 435 p += 2;
s_ain 0:d0117f54a7ee 436 length -= 2;
s_ain 0:d0117f54a7ee 437 } while (length >= 2);
s_ain 0:d0117f54a7ee 438 endAAIProgram();
s_ain 0:d0117f54a7ee 439
s_ain 0:d0117f54a7ee 440 if (length != 0)
s_ain 0:d0117f54a7ee 441 {
s_ain 0:d0117f54a7ee 442 byteProgram(address, *p);
s_ain 0:d0117f54a7ee 443 }
s_ain 0:d0117f54a7ee 444 }