File indexing completed on 2025-05-11 08:23:39
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <rtems.h>
0027 #include <string.h>
0028 #include <unistd.h>
0029 #include <stdio.h>
0030 #include <stdint.h>
0031
0032 #include <dev/spi/zynq-qspi-flash.h>
0033 #include <dev/spi/zynq-qspi-flash-defs.h>
0034 #include <dev/spi/jedec_flash.h>
0035
0036
0037
0038
0039 #define ZQSPI_FLASH_TRACE_TRANSFER 0
0040
0041 #if ZQSPI_FLASH_TRACE_TRANSFER
0042 static bool zqspi_trace = 1;
0043 #endif
0044
0045 #if ZQSPI_FLASH_TRACE_TRANSFER
0046 static void zqspi_transfer_trace_header(
0047 const char* message,
0048 const zqspi_transfer_buffer* transfer
0049 )
0050 {
0051 if (zqspi_trace)
0052 printf(" %s: length=%ld in=%ld out=%ld padding=%ld\n",
0053 message, transfer->length, transfer->in,
0054 transfer->out, transfer->padding);
0055 }
0056 #endif
0057
0058 void zqspi_transfer_trace(
0059 const char* message,
0060 const zqspi_transfer_buffer* transfer
0061 )
0062 {
0063 #if ZQSPI_FLASH_TRACE_TRANSFER
0064 if (zqspi_trace)
0065 {
0066 size_t c;
0067 zqspi_transferTraceHeader(message, transfer);
0068 for (c = 0; c < transfer->length; ++c)
0069 {
0070 if ((c % 16) == 0)
0071 {
0072 if (c)
0073 printf("\n");
0074 printf(" %04lx ", c);
0075 }
0076 printf("%02x", transfer->buffer[c + transfer->padding]);
0077 if ((c % 16) == 7)
0078 printf("-");
0079 else
0080 printf(" ");
0081 }
0082 printf("\n");
0083 }
0084 #endif
0085 }
0086
0087 void qspi_reg_write(uint32_t reg, uint32_t value)
0088 {
0089 volatile uint32_t* ap = (uint32_t*)(ZQSPI_QSPI_BASE + reg);
0090 *ap = value;
0091 }
0092
0093 uint32_t qspi_reg_read(uint32_t reg)
0094 {
0095 volatile uint32_t* ap = (uint32_t*)(ZQSPI_QSPI_BASE + reg);
0096 return *ap;
0097 }
0098
0099 static inline uint8_t zqspi_get8(const uint8_t* data)
0100 {
0101 return *data;
0102 }
0103
0104 static inline uint16_t zqspi_get16(const uint8_t* data)
0105 {
0106 return (((uint16_t) data[1]) << 8) | data[0];
0107 }
0108
0109 static void zqspi_transfer_buffer_clear(zqspi_transfer_buffer* transfer)
0110 {
0111 transfer->length = 0;
0112 transfer->padding = 0;
0113 transfer->in = 0;
0114 transfer->out = 0;
0115 }
0116
0117 static void zqspi_transfer_buffer_set_length(
0118 zqspi_transfer_buffer* transfer,
0119 size_t length
0120 )
0121 {
0122 transfer->length = length;
0123 transfer->padding = (4 - (length & 3)) & 3;
0124 transfer->in = transfer->padding;
0125 transfer->out = transfer->padding;
0126 }
0127
0128 static zqspi_error zqspi_transfer_buffer_fill(
0129 zqspi_transfer_buffer* transfer,
0130 const uint8_t data,
0131 size_t length
0132 )
0133 {
0134 if ((transfer->in + length) >= transfer->size) {
0135 return ZQSPI_FLASH_BUFFER_OVERFLOW;
0136 }
0137
0138 memset(transfer->buffer + transfer->in, data, length);
0139
0140 transfer->in += length;
0141
0142 return ZQSPI_FLASH_NO_ERROR;
0143 }
0144
0145 static zqspi_error zqspi_transfer_buffer_set8(
0146 zqspi_transfer_buffer* transfer,
0147 const uint8_t data
0148 )
0149 {
0150 if (transfer->in >= transfer->size) {
0151 return ZQSPI_FLASH_BUFFER_OVERFLOW;
0152 }
0153
0154 volatile uint8_t* p = &transfer->buffer[transfer->in++];
0155 *p = data;
0156
0157 return ZQSPI_FLASH_NO_ERROR;
0158 }
0159
0160 zqspi_error zqspi_transfer_buffer_skip(
0161 zqspi_transfer_buffer* transfer,
0162 const size_t size
0163 )
0164 {
0165 if ((transfer->length - (transfer->out - transfer->padding)) < size) {
0166 return ZQSPI_FLASH_BUFFER_UNDERFLOW;
0167 }
0168
0169 transfer->out += size;
0170 return ZQSPI_FLASH_NO_ERROR;
0171 }
0172
0173 static zqspi_error zqspi_transfer_buffer_get8(
0174 zqspi_transfer_buffer* transfer,
0175 uint8_t* data
0176 )
0177 {
0178 if ((transfer->length - (transfer->out - transfer->padding)) <
0179 sizeof(uint8_t)) {
0180 return ZQSPI_FLASH_BUFFER_UNDERFLOW;
0181 }
0182
0183 *data = transfer->buffer[transfer->out++];
0184
0185 return ZQSPI_FLASH_NO_ERROR;
0186 }
0187
0188 static zqspi_error zqspi_transfer_buffer_get16(
0189 zqspi_transfer_buffer* transfer,
0190 uint16_t* data
0191 )
0192 {
0193 if ((transfer->length - (transfer->out - transfer->padding)) <
0194 sizeof(uint16_t)) {
0195 return ZQSPI_FLASH_BUFFER_UNDERFLOW;
0196 }
0197
0198 *data = ((uint16_t) transfer->buffer[transfer->out++]) << 8;
0199 *data |= transfer->buffer[transfer->out++];
0200
0201 return ZQSPI_FLASH_NO_ERROR;
0202 }
0203
0204 static zqspi_error zqspi_transfer_buffer_copy_out(
0205 zqspi_transfer_buffer* transfer,
0206 uint8_t* data,
0207 const size_t length
0208 )
0209 {
0210 if ((transfer->length - (transfer->out - transfer->padding)) < length) {
0211 return ZQSPI_FLASH_BUFFER_UNDERFLOW;
0212 }
0213 memcpy(data, transfer->buffer + transfer->out, length);
0214 transfer->out += length;
0215
0216 return ZQSPI_FLASH_NO_ERROR;
0217 }
0218
0219 static zqspi_error zqspi_transfer_buffer_copy_in(
0220 zqspi_transfer_buffer* transfer,
0221 const uint8_t* data,
0222 const size_t length
0223 )
0224 {
0225 if ((transfer->in + length) > transfer->size) {
0226 return ZQSPI_FLASH_BUFFER_OVERFLOW;
0227 }
0228
0229 memcpy(transfer->buffer + transfer->in, data, length);
0230 transfer->in += length;
0231
0232 return ZQSPI_FLASH_NO_ERROR;
0233 }
0234
0235 static void zqspi_transfer_buffer_set_addr(
0236 zqspi_transfer_buffer* transfer,
0237 uint32_t address
0238 )
0239 {
0240 #if ZQSPI_FLASH_4BYTE_ADDRESSING
0241 zqspi_transfer_buffer_set8(transfer, (address >> 24) & 0xff);
0242 #endif
0243 zqspi_transfer_buffer_set8(transfer, (address >> 16) & 0xff);
0244 zqspi_transfer_buffer_set8(transfer, (address >> 8) & 0xff);
0245 zqspi_transfer_buffer_set8(transfer, address & 0xff);
0246 }
0247
0248 static void zqspi_transfer_buffer_set_dir(
0249 zqspi_transfer_buffer* transfer,
0250 int trans_dir
0251 )
0252 {
0253 transfer->trans_dir = trans_dir;
0254 }
0255
0256 static void zqspi_transfer_buffer_set_command_len(
0257 zqspi_transfer_buffer* transfer,
0258 int comm_len
0259 )
0260 {
0261 transfer->command_len = comm_len;
0262 }
0263
0264 static zqspi_error zqspi_read_register(
0265 zqspiflash *driver,
0266 uint8_t reg,
0267 uint16_t* value
0268 )
0269 {
0270 zqspi_error fe;
0271
0272 zqspi_transfer_buffer_clear(&driver->buf);
0273 zqspi_transfer_buffer_set_length(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE + 2);
0274 zqspi_transfer_buffer_set8(&driver->buf, reg);
0275 zqspi_transfer_buffer_set8(&driver->buf, 0);
0276 zqspi_transfer_buffer_set8(&driver->buf, 0);
0277 zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_RX_TRANS);
0278 zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE);
0279
0280 fe = zqspi_transfer(&driver->buf, &driver->initialised);
0281 if (fe != ZQSPI_FLASH_NO_ERROR)
0282 return fe;
0283
0284 zqspi_transfer_buffer_get16(&driver->buf, value);
0285
0286 return ZQSPI_FLASH_NO_ERROR;
0287 }
0288
0289 static zqspi_error zqspi_wait_for_write(zqspiflash *driver, uint32_t wait)
0290 {
0291 uint16_t status;
0292 zqspi_error fe;
0293 uint32_t checks = 100;
0294
0295 while (true) {
0296 fe = zqspi_read_register(driver, ZQSPI_FLASH_READ_STATUS_FLAG_CMD, &status);
0297 if (fe != ZQSPI_FLASH_NO_ERROR) {
0298 return fe;
0299 }
0300
0301 status = status & 0xFF;
0302
0303 if ((status & ZQSPI_FLASH_SR_E_ERR) != 0) {
0304 return ZQSPI_FLASH_ERASE_FAILURE;
0305 }
0306
0307
0308
0309
0310
0311
0312
0313 fe = zqspi_read_register(driver, ZQSPI_FLASH_READ_STATUS_CMD, &status);
0314 status = status & 0xFF;
0315 if (fe != ZQSPI_FLASH_NO_ERROR) {
0316 return fe;
0317 }
0318
0319 if ((status & ZQSPI_FLASH_SR_WIP) == 0)
0320 {
0321 if ((status & ZQSPI_FLASH_SR_WEL) == 0) {
0322 break;
0323 }
0324 if (checks == 0) {
0325 return ZQSPI_FLASH_WRITE_ERASE_CMD_FAIL;
0326 }
0327 --checks;
0328 }
0329
0330 if (wait) {
0331 usleep(wait);
0332 }
0333 }
0334 return ZQSPI_FLASH_NO_ERROR;
0335 }
0336
0337 static zqspi_error zqspi_set_WEL(zqspiflash *driver)
0338 {
0339 uint16_t status;
0340 zqspi_error fe;
0341
0342 zqspi_transfer_buffer_clear(&driver->buf);
0343 zqspi_transfer_buffer_set_length(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE);
0344 zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_WRITE_ENABLE_CMD);
0345 zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
0346 zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE);
0347
0348 fe = zqspi_transfer(&driver->buf, &driver->initialised);
0349 if (fe != ZQSPI_FLASH_NO_ERROR) {
0350 return fe;
0351 }
0352
0353 fe = zqspi_read_register(driver, ZQSPI_FLASH_READ_STATUS_CMD, &status);
0354 if (fe != ZQSPI_FLASH_NO_ERROR) {
0355 return fe;
0356 }
0357
0358 if ((status & ZQSPI_FLASH_SR_WEL) == 0) {
0359 return ZQSPI_FLASH_READ_ONLY;
0360 }
0361
0362 return ZQSPI_FLASH_NO_ERROR;
0363 }
0364
0365 static zqspi_error zqspi_clear_WEL(zqspiflash *driver) {
0366 uint16_t status;
0367 zqspi_error fe;
0368
0369 zqspi_transfer_buffer_clear(&driver->buf);
0370 zqspi_transfer_buffer_set_length(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE);
0371 zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_WRITE_DISABLE_CMD);
0372 zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
0373 zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE);
0374
0375 fe = zqspi_transfer(&driver->buf, &driver->initialised);
0376 if (fe != ZQSPI_FLASH_NO_ERROR) {
0377 return fe;
0378 }
0379
0380 fe = zqspi_read_register(driver, ZQSPI_FLASH_READ_STATUS_CMD, &status);
0381 if (fe != ZQSPI_FLASH_NO_ERROR) {
0382 return fe;
0383 }
0384
0385 if ((status & ZQSPI_FLASH_SR_WEL) != 0) {
0386 return ZQSPI_FLASH_WRITE_LATCH_CLEAR_FAIL;
0387 }
0388
0389 return ZQSPI_FLASH_NO_ERROR;
0390 }
0391
0392 zqspi_error zqspi_read(
0393 zqspiflash *driver,
0394 uint32_t address,
0395 void* buffer,
0396 size_t length
0397 )
0398 {
0399 uint8_t* data = buffer;
0400
0401 while (length)
0402 {
0403 zqspi_error fe;
0404 size_t size;
0405
0406 if (driver->flash_page_size == 0) {
0407 return ZQSPI_FLASH_INVALID_DEVICE;
0408 }
0409 size = length > driver->flash_page_size ? driver->flash_page_size : length;
0410
0411 zqspi_transfer_buffer_clear(&driver->buf);
0412 zqspi_transfer_buffer_set_length(
0413 &driver->buf,
0414 ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE +
0415 driver->flash_read_dummies + size
0416 );
0417 zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_READ_CMD);
0418 zqspi_transfer_buffer_set_addr(&driver->buf, address);
0419 fe = zqspi_transfer_buffer_fill(&driver->buf, 0,
0420 driver->flash_read_dummies + size);
0421 if (fe != ZQSPI_FLASH_NO_ERROR) {
0422 return fe;
0423 }
0424 zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_RX_TRANS);
0425 zqspi_transfer_buffer_set_command_len(&driver->buf,
0426 ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE +
0427 driver->flash_read_dummies);
0428
0429 fe = zqspi_transfer(&driver->buf, &driver->initialised);
0430 if (fe != ZQSPI_FLASH_NO_ERROR) {
0431 return fe;
0432 }
0433
0434 zqspi_transfer_buffer_skip(&driver->buf,
0435 ZQSPI_FLASH_ADDRESS_SIZE + driver->flash_read_dummies);
0436
0437 fe = zqspi_transfer_buffer_copy_out(&driver->buf, data, size);
0438 if (fe != ZQSPI_FLASH_NO_ERROR) {
0439 return fe;
0440 }
0441
0442 length -= size;
0443 data += size;
0444 address += size;
0445 }
0446
0447 return ZQSPI_FLASH_NO_ERROR;
0448 }
0449
0450 zqspi_error zqspi_blank(zqspiflash *driver, uint32_t address, size_t length)
0451 {
0452 zqspi_error fe = ZQSPI_FLASH_NO_ERROR;
0453
0454 if (
0455 (address >= driver->flash_size) ||
0456 ((address + length) > driver->flash_size)
0457 )
0458 {
0459 return ZQSPI_FLASH_BAD_ADDRESS;
0460 }
0461
0462 while (length)
0463 {
0464 size_t size;
0465
0466 if (driver->flash_page_size == 0) {
0467 return ZQSPI_FLASH_INVALID_DEVICE;
0468 }
0469 size = length > driver->flash_page_size ? driver->flash_page_size : length;
0470
0471 zqspi_transfer_buffer_clear(&driver->buf);
0472 zqspi_transfer_buffer_set_length(&driver->buf,
0473 ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE
0474 + driver->flash_read_dummies + size);
0475 zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_READ_CMD);
0476 zqspi_transfer_buffer_set_addr(&driver->buf, address);
0477 fe = zqspi_transfer_buffer_fill(&driver->buf, 0,
0478 driver->flash_read_dummies + size);
0479 if (fe != ZQSPI_FLASH_NO_ERROR) {
0480 return fe;
0481 }
0482 zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_RX_TRANS);
0483 zqspi_transfer_buffer_set_command_len(&driver->buf,
0484 ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE
0485 + driver->flash_read_dummies);
0486
0487 fe = zqspi_transfer(&driver->buf, &driver->initialised);
0488 if (fe != ZQSPI_FLASH_NO_ERROR) {
0489 return fe;
0490 }
0491
0492 zqspi_transfer_buffer_skip(&driver->buf, ZQSPI_FLASH_ADDRESS_SIZE);
0493
0494 length -= size;
0495 address += size;
0496
0497 while (size) {
0498 uint8_t byte = 0;
0499 zqspi_transfer_buffer_get8(&driver->buf, &byte);
0500 if (byte != 0xff) {
0501 return ZQSPI_FLASH_NOT_BLANK;
0502 }
0503 --size;
0504 }
0505 }
0506
0507 return fe;
0508 }
0509
0510 zqspi_error zqspi_erase(zqspiflash *driver, uint32_t address, size_t length)
0511 {
0512 zqspi_error fe = ZQSPI_FLASH_NO_ERROR;
0513 bool done = false;
0514
0515 if (
0516 (address >= driver->flash_size) ||
0517 ((address + length) > driver->flash_size)
0518 ) {
0519 return ZQSPI_FLASH_BAD_ADDRESS;
0520 }
0521 if (driver->flash_page_size == 0) {
0522 return ZQSPI_FLASH_INVALID_DEVICE;
0523 }
0524
0525 while (!done) {
0526 fe = zqspi_erase_sector(driver,
0527 (address - (address%(driver->flash_erase_sector_size))));
0528 if (fe != ZQSPI_FLASH_NO_ERROR) {
0529 return fe;
0530 }
0531
0532 if (length <= driver->flash_erase_sector_size) {
0533 done = true;
0534 } else {
0535 address += driver->flash_erase_sector_size;
0536 length -= driver->flash_erase_sector_size;
0537 }
0538 }
0539 return fe;
0540 }
0541
0542 zqspi_error zqspi_erase_sector(zqspiflash *driver, uint32_t address)
0543 {
0544 zqspi_error fe = ZQSPI_FLASH_NO_ERROR;
0545 uint32_t base = 0;
0546 size_t length = 0;
0547
0548 if (
0549 (address >= driver->flash_size) ||
0550 ((address + length) > driver->flash_size)
0551 )
0552 {
0553 return ZQSPI_FLASH_BAD_ADDRESS;
0554 }
0555
0556 zqspi_write_unlock(driver);
0557
0558 fe = zqspi_set_WEL(driver);
0559 if (fe != ZQSPI_FLASH_NO_ERROR)
0560 {
0561 zqspi_write_lock(driver);
0562 return fe;
0563 }
0564
0565 zqspi_transfer_buffer_clear(&driver->buf);
0566 zqspi_transfer_buffer_set_length(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE
0567 + ZQSPI_FLASH_ADDRESS_SIZE);
0568 zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_SEC_ERASE_CMD);
0569 zqspi_transfer_buffer_set_addr(&driver->buf, address);
0570 zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
0571 zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE
0572 + ZQSPI_FLASH_ADDRESS_SIZE);
0573
0574 fe = zqspi_transfer(&driver->buf, &driver->initialised);
0575 if (fe != ZQSPI_FLASH_NO_ERROR)
0576 {
0577 zqspi_clear_WEL(driver);
0578 zqspi_write_lock(driver);
0579 return fe;
0580 }
0581
0582 fe = zqspi_wait_for_write(driver, 1000);
0583 if (fe != ZQSPI_FLASH_NO_ERROR)
0584 {
0585 zqspi_clear_WEL(driver);
0586 zqspi_write_lock(driver);
0587 return fe;
0588 }
0589
0590 zqspi_write_lock(driver);
0591
0592 fe = zqspi_blank(driver, base, length);
0593 if (fe != ZQSPI_FLASH_NO_ERROR)
0594 return fe;
0595
0596 return fe;
0597 }
0598
0599 zqspi_error zqspi_erase_device(zqspiflash *driver)
0600 {
0601 zqspi_error fe = ZQSPI_FLASH_NO_ERROR;
0602
0603 zqspi_write_unlock(driver);
0604
0605 fe = zqspi_set_WEL(driver);
0606 if (fe != ZQSPI_FLASH_NO_ERROR)
0607 {
0608 zqspi_write_lock(driver);
0609 return fe;
0610 }
0611
0612 zqspi_transfer_buffer_clear(&driver->buf);
0613 zqspi_transfer_buffer_set_length(&driver->buf, 1);
0614 zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_BULK_ERASE_CMD);
0615 zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
0616 zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE);
0617
0618 fe = zqspi_transfer(&driver->buf, &driver->initialised);
0619 if (fe != ZQSPI_FLASH_NO_ERROR)
0620 {
0621 zqspi_clear_WEL(driver);
0622 zqspi_write_lock(driver);
0623 return fe;
0624 }
0625
0626 fe = zqspi_wait_for_write(driver, 1000000);
0627 if (fe != ZQSPI_FLASH_NO_ERROR)
0628 {
0629 zqspi_clear_WEL(driver);
0630 zqspi_write_lock(driver);
0631 return fe;
0632 }
0633
0634 zqspi_write_lock(driver);
0635
0636 return fe;
0637 }
0638
0639 zqspi_error zqspi_write(
0640 zqspiflash *driver,
0641 uint32_t address,
0642 const void* buffer,
0643 size_t length
0644 )
0645 {
0646 zqspi_error fe = ZQSPI_FLASH_NO_ERROR;
0647 const uint8_t* data = buffer;
0648 size_t size;
0649 size_t byte;
0650 bool write_block = false;
0651
0652 if (
0653 (address >= driver->flash_size) ||
0654 ((address + length) > driver->flash_size)
0655 )
0656 {
0657 return ZQSPI_FLASH_BAD_ADDRESS;
0658 }
0659
0660 zqspi_write_unlock(driver);
0661
0662 while (length) {
0663 if (driver->flash_page_size == 0) {
0664 return ZQSPI_FLASH_INVALID_DEVICE;
0665 }
0666 size = length > driver->flash_page_size ? driver->flash_page_size : length;
0667
0668
0669
0670
0671
0672 if ((address % driver->flash_page_size) != 0)
0673 {
0674 size_t remaining = driver->flash_page_size
0675 - (address % driver->flash_page_size);
0676 if (size > remaining)
0677 size = remaining;
0678 }
0679
0680
0681
0682
0683 for (byte = 0; byte < size; ++byte)
0684 {
0685 if (data[byte] != 0xff)
0686 {
0687 write_block = true;
0688 break;
0689 }
0690 }
0691
0692 if (write_block)
0693 {
0694 fe = zqspi_set_WEL(driver);
0695 if (fe != ZQSPI_FLASH_NO_ERROR)
0696 {
0697 zqspi_write_lock(driver);
0698 return fe;
0699 }
0700
0701 zqspi_transfer_buffer_clear(&driver->buf);
0702 zqspi_transfer_buffer_set_length(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE
0703 + ZQSPI_FLASH_ADDRESS_SIZE + size);
0704 zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_WRITE_CMD);
0705 zqspi_transfer_buffer_set_addr(&driver->buf, address);
0706 zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
0707 zqspi_transfer_buffer_set_command_len(&driver->buf,
0708 ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE);
0709 fe = zqspi_transfer_buffer_copy_in(&driver->buf, data, size);
0710 if (fe != ZQSPI_FLASH_NO_ERROR)
0711 {
0712 zqspi_write_lock(driver);
0713 return fe;
0714 }
0715
0716 fe = zqspi_transfer(&driver->buf, &driver->initialised);
0717 if (fe != ZQSPI_FLASH_NO_ERROR)
0718 {
0719 zqspi_clear_WEL(driver);
0720 zqspi_write_lock(driver);
0721 return fe;
0722 }
0723
0724 fe = zqspi_wait_for_write(driver, 1000);
0725 if (fe != ZQSPI_FLASH_NO_ERROR)
0726 {
0727 zqspi_clear_WEL(driver);
0728 zqspi_write_lock(driver);
0729 return fe;
0730 }
0731 }
0732
0733 address += size;
0734 data += size;
0735 length -= size;
0736 }
0737
0738 zqspi_write_lock(driver);
0739
0740 return fe;
0741 }
0742
0743 zqspi_error zqspi_readid(zqspiflash *driver, uint32_t *jedec_id)
0744 {
0745 zqspi_error fe;
0746 uint8_t value = 0;
0747 int index = 0;
0748
0749 if (driver->jedec_id != 0) {
0750 if (jedec_id != NULL) {
0751 *jedec_id = driver->jedec_id;
0752 }
0753 return ZQSPI_FLASH_NO_ERROR;
0754 }
0755
0756 zqspi_transfer_buffer_clear(&driver->buf);
0757 zqspi_transfer_buffer_set_length(&driver->buf, 1 + 3);
0758 zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_READ_ID);
0759 zqspi_transfer_buffer_fill(&driver->buf, 0x00, 3);
0760 zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_RX_TRANS);
0761 zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE);
0762
0763 fe = zqspi_transfer(&driver->buf, &driver->initialised);
0764 if (fe != ZQSPI_FLASH_NO_ERROR)
0765 return fe;
0766
0767 zqspi_transfer_buffer_get8(&driver->buf, &value);
0768 driver->jedec_id |= value << 16;
0769 zqspi_transfer_buffer_get8(&driver->buf, &value);
0770 driver->jedec_id |= value << 8;
0771 zqspi_transfer_buffer_get8(&driver->buf, &value);
0772 driver->jedec_id |= value;
0773
0774 if (jedec_id != NULL) {
0775 *jedec_id = driver->jedec_id;
0776 }
0777
0778 while (flash_dev_table[index].jedec_id != driver->jedec_id) {
0779 if (flash_dev_table[index].jedec_id == 0) {
0780 return ZQSPI_FLASH_INVALID_DEVICE;
0781 }
0782 index++;
0783 }
0784 driver->flash_size = flash_dev_table[index].flash_size;
0785 driver->flash_erase_sector_size = flash_dev_table[index].sec_size;
0786 driver->flash_page_size = flash_dev_table[index].page_size;
0787 #if ZQSPI_FLASH_FAST_READ
0788 driver->flash_read_dummies = 1;
0789 #endif
0790
0791 return ZQSPI_FLASH_NO_ERROR;
0792 }
0793
0794 size_t zqspi_device_size(zqspiflash *driver)
0795 {
0796 return driver->flash_size;
0797 }
0798
0799 size_t zqspi_device_sector_erase_size(zqspiflash *driver)
0800 {
0801 return driver->flash_erase_sector_size;
0802 }
0803
0804 zqspi_error zqspi_init(zqspiflash *driver)
0805 {
0806 rtems_status_code sc;
0807 uint8_t *zqspizqspi_buf = calloc(1, ZQSPI_FLASH_BUFFER_SIZE);
0808
0809 driver->buf.size = ZQSPI_FLASH_BUFFER_SIZE;
0810 driver->buf.length = 0;
0811 driver->buf.padding = 0;
0812 driver->buf.in = 0;
0813 driver->buf.out = 0;
0814 driver->buf.trans_dir = 0;
0815 driver->buf.command_len = 0;
0816 driver->buf.buffer = zqspizqspi_buf;
0817 driver->buf.tx_data = NULL;
0818 driver->buf.rx_data = NULL;
0819 driver->buf.tx_length = 0;
0820 driver->buf.rx_length = 0;
0821 driver->buf.sending = 0;
0822 driver->buf.start = false;
0823 driver->initialised = false;
0824 driver->jedec_id = 0;
0825 driver->flash_size = 0;
0826 driver->flash_read_dummies = 0;
0827 driver->flash_erase_sector_size = 0;
0828 driver->flash_page_size = 0;
0829
0830 sc = rtems_interrupt_handler_install(
0831 ZQPSI_ZYNQ_QSPI_IRQ,
0832 NULL,
0833 RTEMS_INTERRUPT_UNIQUE,
0834 (rtems_interrupt_handler) zqspi_transfer_intr,
0835 driver
0836 );
0837 if (sc != RTEMS_SUCCESSFUL) {
0838 free(driver->buf.buffer);
0839 return ZQSPI_FLASH_RTEMS_INTR;
0840 }
0841
0842 return zqspi_readid(driver, NULL);
0843 }
0844
0845 void zqspi_close(zqspiflash *driver)
0846 {
0847 free(driver->buf.buffer);
0848 }